diff options
Diffstat (limited to '')
-rw-r--r-- | dnsdist-nghttp2-in.cc | 46 |
1 files changed, 38 insertions, 8 deletions
diff --git a/dnsdist-nghttp2-in.cc b/dnsdist-nghttp2-in.cc index 32dc254..e40f5e6 100644 --- a/dnsdist-nghttp2-in.cc +++ b/dnsdist-nghttp2-in.cc @@ -222,8 +222,9 @@ void IncomingHTTP2Connection::handleResponse(const struct timeval& now, TCPRespo std::unique_ptr<DOHUnitInterface> IncomingHTTP2Connection::getDOHUnit(uint32_t streamID) { - // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay): clang-tidy is getting confused by assert() - assert(streamID <= std::numeric_limits<IncomingHTTP2Connection::StreamID>::max()); + if (streamID > std::numeric_limits<IncomingHTTP2Connection::StreamID>::max()) { + throw std::runtime_error("Invalid stream ID while retrieving DoH unit"); + } // NOLINTNEXTLINE(*-narrowing-conversions): generic interface between DNS and DoH with different types auto query = std::move(d_currentStreams.at(static_cast<IncomingHTTP2Connection::StreamID>(streamID))); return std::make_unique<IncomingDoHCrossProtocolContext>(std::move(query), std::dynamic_pointer_cast<IncomingHTTP2Connection>(shared_from_this()), streamID); @@ -330,6 +331,27 @@ IOState IncomingHTTP2Connection::handleHandshake(const struct timeval& now) return iostate; } +class ReadFunctionGuard +{ +public: + ReadFunctionGuard(bool& inReadFunction) : + d_inReadFunctionRef(inReadFunction) + { + d_inReadFunctionRef = true; + } + ReadFunctionGuard(ReadFunctionGuard&&) = delete; + ReadFunctionGuard(const ReadFunctionGuard&) = delete; + ReadFunctionGuard& operator=(ReadFunctionGuard&&) = delete; + ReadFunctionGuard& operator=(const ReadFunctionGuard&) = delete; + ~ReadFunctionGuard() + { + d_inReadFunctionRef = false; + } + +private: + bool& d_inReadFunctionRef; +}; + void IncomingHTTP2Connection::handleIO() { IOState iostate = IOState::Done; @@ -392,10 +414,10 @@ void IncomingHTTP2Connection::handleIO() } } - if (active() && !d_connectionClosing && (d_state == State::waitingForQuery || d_state == State::idle)) { + if (!d_inReadFunction && active() && !d_connectionClosing && (d_state == State::waitingForQuery || d_state == State::idle)) { do { iostate = readHTTPData(); - } while (active() && !d_connectionClosing && iostate == IOState::Done); + } while (!d_inReadFunction && active() && !d_connectionClosing && iostate == IOState::Done); } if (!active()) { @@ -530,8 +552,9 @@ void NGHTTP2Headers::addDynamicHeader(std::vector<nghttp2_nv>& headers, NGHTTP2H IOState IncomingHTTP2Connection::sendResponse(const struct timeval& now, TCPResponse&& response) { - // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay): clang-tidy is getting confused by assert() - assert(response.d_idstate.d_streamID != -1); + if (response.d_idstate.d_streamID == -1) { + throw std::runtime_error("Invalid DoH stream ID while sending response"); + } auto& context = d_currentStreams.at(response.d_idstate.d_streamID); uint32_t statusCode = 200U; @@ -562,8 +585,10 @@ void IncomingHTTP2Connection::notifyIOError(const struct timeval& now, TCPRespon return; } - // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay): clang-tidy is getting confused by assert() - assert(response.d_idstate.d_streamID != -1); + if (response.d_idstate.d_streamID == -1) { + throw std::runtime_error("Invalid DoH stream ID while handling I/O error notification"); + } + auto& context = d_currentStreams.at(response.d_idstate.d_streamID); context.d_buffer = std::move(response.d_buffer); sendResponse(response.d_idstate.d_streamID, context, 502, d_ci.cs->dohFrontend->d_customResponseHeaders); @@ -1064,6 +1089,11 @@ int IncomingHTTP2Connection::on_error_callback(nghttp2_session* session, int lib IOState IncomingHTTP2Connection::readHTTPData() { + if (d_inReadFunction) { + return IOState::Done; + } + ReadFunctionGuard readGuard(d_inReadFunction); + IOState newState = IOState::Done; size_t got = 0; if (d_in.size() < s_initialReceiveBufferSize) { |