summaryrefslogtreecommitdiffstats
path: root/dnsdist-nghttp2-in.cc
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--dnsdist-nghttp2-in.cc46
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) {