// * so let's go back
}
#else /* ifndef DNSDIST */
+ (void)key;
+ (void)data;
+ (void)op;
return rc;
#endif
}
}
#endif /* DISABLE_CARBON */
-static time_t s_start = time(nullptr);
+static const time_t s_start = time(nullptr);
uint64_t uptimeOfProcess(const std::string& str)
{
+ (void)str;
return time(nullptr) - s_start;
}
static char** dnsdist_completion_callback(const char* text, int start, int end)
{
+ (void)end;
char** matches = nullptr;
if (start == 0) {
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast): readline
const auto& it = d_downstreamConnections.find(backendId);
if (it != d_downstreamConnections.end()) {
/* first scan idle connections, more recent first */
- auto entry = findUsableConnectionInList(now, freshCutOff, it->second.d_idles, true);
+ auto entry = findUsableConnectionInList(freshCutOff, it->second.d_idles, true);
if (entry) {
++ds->tcpReusedConnections;
it->second.d_actives.insert(entry);
}
/* then scan actives ones, more recent first as well */
- entry = findUsableConnectionInList(now, freshCutOff, it->second.d_actives, false);
+ entry = findUsableConnectionInList(freshCutOff, it->second.d_actives, false);
if (entry) {
++ds->tcpReusedConnections;
return entry;
idleCutOff.tv_sec -= s_maxIdleTime;
for (auto dsIt = d_downstreamConnections.begin(); dsIt != d_downstreamConnections.end();) {
- cleanUpList(dsIt->second.d_idles, now, freshCutOff, idleCutOff);
- cleanUpList(dsIt->second.d_actives, now, freshCutOff, idleCutOff);
+ cleanUpList(dsIt->second.d_idles, freshCutOff, idleCutOff);
+ cleanUpList(dsIt->second.d_actives, freshCutOff, idleCutOff);
if (dsIt->second.d_idles.empty() && dsIt->second.d_actives.empty()) {
dsIt = d_downstreamConnections.erase(dsIt);
}
protected:
- void cleanUpList(list_t& list, const struct timeval& now, const struct timeval& freshCutOff, const struct timeval& idleCutOff)
+ void cleanUpList(list_t& list, const struct timeval& freshCutOff, const struct timeval& idleCutOff)
{
auto& sidx = list.template get<SequencedTag>();
for (auto connIt = sidx.begin(); connIt != sidx.end();) {
}
}
- std::shared_ptr<T> findUsableConnectionInList(const struct timeval& now, const struct timeval& freshCutOff, list_t& list, bool removeIfFound)
+ std::shared_ptr<T> findUsableConnectionInList(const struct timeval& freshCutOff, list_t& list, bool removeIfFound)
{
auto& sidx = list.template get<SequencedTag>();
for (auto listIt = sidx.begin(); listIt != sidx.end();) {
}
auto& entry = *listIt;
- if (isConnectionUsable(entry, now, freshCutOff)) {
+ if (isConnectionUsable(entry, freshCutOff)) {
entry->setReused();
// make a copy since the iterator will be invalidated after erasing
auto result = entry;
return nullptr;
}
- bool isConnectionUsable(const std::shared_ptr<T>& conn, const struct timeval& now, const struct timeval& freshCutOff)
+ bool isConnectionUsable(const std::shared_ptr<T>& conn, const struct timeval& freshCutOff)
{
if (!conn->canBeReused()) {
return false;
void handleResponse(const struct timeval& now, TCPResponse&& response) override
{
+ (void)now;
d_data->d_buffer = std::move(response.d_buffer);
d_data->d_ds->submitHealthCheckResult(d_data->d_initial, ::handleResponse(d_data));
}
void handleXFRResponse(const struct timeval& now, TCPResponse&& response) override
{
+ (void)now;
+ (void)response;
throw std::runtime_error("Unexpected XFR reponse to a health check query");
}
void notifyIOError(const struct timeval& now, [[maybe_unused]] TCPResponse&& response) override
{
+ (void)now;
+ (void)response;
++d_data->d_ds->d_healthCheckMetrics.d_networkErrors;
d_data->d_ds->submitHealthCheckResult(d_data->d_initial, false);
}
static void healthCheckTCPCallback(int descriptor, FDMultiplexer::funcparam_t& param)
{
+ (void)descriptor;
auto data = boost::any_cast<std::shared_ptr<HealthCheckData>>(param);
IOStateGuard ioGuard(data->d_ioState);
// This requires that the underlying store supports ordered keys, which is true for LMDB but not for CDB, for example.
virtual bool getRangeValue(const std::string& key, std::string& value)
{
+ (void)key;
+ (void)value;
throw std::runtime_error("range-based lookups are not implemented for this Key-Value Store");
}
virtual bool reload()
/* DNSQuestion */
/* PowerDNS DNSQuestion compat */
luaCtx.registerMember<const ComboAddress(DNSQuestion::*)>(
- "localaddr", [](const DNSQuestion& dnsQuestion) -> ComboAddress { return dnsQuestion.ids.origDest; }, [](DNSQuestion& dnsQuestion, const ComboAddress newLocal) { (void)newLocal; });
+ "localaddr", [](const DNSQuestion& dnsQuestion) -> ComboAddress { return dnsQuestion.ids.origDest; }, [](DNSQuestion& dnsQuestion, const ComboAddress newLocal) { (void)dnsQuestion; (void)newLocal; });
luaCtx.registerMember<const DNSName(DNSQuestion::*)>(
- "qname", [](const DNSQuestion& dnsQuestion) -> DNSName { return dnsQuestion.ids.qname; }, [](DNSQuestion& dnsQuestion, const DNSName& newName) { (void)newName; });
+ "qname", [](const DNSQuestion& dnsQuestion) -> DNSName { return dnsQuestion.ids.qname; }, [](DNSQuestion& dnsQuestion, const DNSName& newName) { (void)dnsQuestion; (void)newName; });
luaCtx.registerMember<uint16_t(DNSQuestion::*)>(
- "qtype", [](const DNSQuestion& dnsQuestion) -> uint16_t { return dnsQuestion.ids.qtype; }, [](DNSQuestion& dnsQuestion, uint16_t newType) { (void)newType; });
+ "qtype", [](const DNSQuestion& dnsQuestion) -> uint16_t { return dnsQuestion.ids.qtype; }, [](DNSQuestion& dnsQuestion, uint16_t newType) { (void)dnsQuestion; (void)newType; });
luaCtx.registerMember<uint16_t(DNSQuestion::*)>(
- "qclass", [](const DNSQuestion& dnsQuestion) -> uint16_t { return dnsQuestion.ids.qclass; }, [](DNSQuestion& dnsQuestion, uint16_t newClass) { (void)newClass; });
+ "qclass", [](const DNSQuestion& dnsQuestion) -> uint16_t { return dnsQuestion.ids.qclass; }, [](DNSQuestion& dnsQuestion, uint16_t newClass) { (void)dnsQuestion; (void)newClass; });
luaCtx.registerMember<int(DNSQuestion::*)>(
"rcode",
[](const DNSQuestion& dnsQuestion) -> int {
});
});
luaCtx.registerMember<const ComboAddress(DNSQuestion::*)>(
- "remoteaddr", [](const DNSQuestion& dnsQuestion) -> ComboAddress { return dnsQuestion.ids.origRemote; }, [](DNSQuestion& dnsQuestion, const ComboAddress newRemote) { (void)newRemote; });
+ "remoteaddr", [](const DNSQuestion& dnsQuestion) -> ComboAddress { return dnsQuestion.ids.origRemote; }, [](DNSQuestion& dnsQuestion, const ComboAddress newRemote) { (void)dnsQuestion; (void)newRemote; });
/* DNSDist DNSQuestion */
luaCtx.registerMember<dnsheader*(DNSQuestion::*)>(
"dh",
luaCtx.registerMember<uint16_t(DNSQuestion::*)>(
"len", [](const DNSQuestion& dnsQuestion) -> uint16_t { return dnsQuestion.getData().size(); }, [](DNSQuestion& dnsQuestion, uint16_t newlen) { dnsQuestion.getMutableData().resize(newlen); });
luaCtx.registerMember<uint8_t(DNSQuestion::*)>(
- "opcode", [](const DNSQuestion& dnsQuestion) -> uint8_t { return dnsQuestion.getHeader()->opcode; }, [](DNSQuestion& dnsQuestion, uint8_t newOpcode) { (void)newOpcode; });
+ "opcode", [](const DNSQuestion& dnsQuestion) -> uint8_t { return dnsQuestion.getHeader()->opcode; }, [](DNSQuestion& dnsQuestion, uint8_t newOpcode) { (void)dnsQuestion; (void)newOpcode; });
luaCtx.registerMember<bool(DNSQuestion::*)>(
- "tcp", [](const DNSQuestion& dnsQuestion) -> bool { return dnsQuestion.overTCP(); }, [](DNSQuestion& dnsQuestion, bool newTcp) { (void)newTcp; });
+ "tcp", [](const DNSQuestion& dnsQuestion) -> bool { return dnsQuestion.overTCP(); }, [](DNSQuestion& dnsQuestion, bool newTcp) { (void)dnsQuestion; (void)newTcp; });
luaCtx.registerMember<bool(DNSQuestion::*)>(
"skipCache", [](const DNSQuestion& dnsQuestion) -> bool { return dnsQuestion.ids.skipCache; }, [](DNSQuestion& dnsQuestion, bool newSkipCache) { dnsQuestion.ids.skipCache = newSkipCache; });
luaCtx.registerMember<std::string(DNSQuestion::*)>(
/* LuaWrapper doesn't support inheritance */
luaCtx.registerMember<const ComboAddress(DNSResponse::*)>(
- "localaddr", [](const DNSResponse& dnsQuestion) -> ComboAddress { return dnsQuestion.ids.origDest; }, [](DNSResponse& dnsQuestion, const ComboAddress newLocal) { (void)newLocal; });
+ "localaddr", [](const DNSResponse& dnsQuestion) -> ComboAddress { return dnsQuestion.ids.origDest; }, [](DNSResponse& dnsQuestion, const ComboAddress newLocal) { (void)dnsQuestion; (void)newLocal; });
luaCtx.registerMember<const DNSName(DNSResponse::*)>(
- "qname", [](const DNSResponse& dnsQuestion) -> DNSName { return dnsQuestion.ids.qname; }, [](DNSResponse& dnsQuestion, const DNSName& newName) { (void)newName; });
+ "qname", [](const DNSResponse& dnsQuestion) -> DNSName { return dnsQuestion.ids.qname; }, [](DNSResponse& dnsQuestion, const DNSName& newName) { (void)dnsQuestion; (void)newName; });
luaCtx.registerMember<uint16_t(DNSResponse::*)>(
- "qtype", [](const DNSResponse& dnsQuestion) -> uint16_t { return dnsQuestion.ids.qtype; }, [](DNSResponse& dnsQuestion, uint16_t newType) { (void)newType; });
+ "qtype", [](const DNSResponse& dnsQuestion) -> uint16_t { return dnsQuestion.ids.qtype; }, [](DNSResponse& dnsQuestion, uint16_t newType) { (void)dnsQuestion; (void)newType; });
luaCtx.registerMember<uint16_t(DNSResponse::*)>(
- "qclass", [](const DNSResponse& dnsQuestion) -> uint16_t { return dnsQuestion.ids.qclass; }, [](DNSResponse& dnsQuestion, uint16_t newClass) { (void)newClass; });
+ "qclass", [](const DNSResponse& dnsQuestion) -> uint16_t { return dnsQuestion.ids.qclass; }, [](DNSResponse& dnsQuestion, uint16_t newClass) { (void)dnsQuestion; (void)newClass; });
luaCtx.registerMember<int(DNSResponse::*)>(
"rcode",
[](const DNSResponse& dnsQuestion) -> int {
});
});
luaCtx.registerMember<ComboAddress(DNSResponse::*)>(
- "remoteaddr", [](const DNSResponse& dnsQuestion) -> ComboAddress { return dnsQuestion.ids.origRemote; }, [](DNSResponse& dnsQuestion, const ComboAddress newRemote) { (void)newRemote; });
+ "remoteaddr", [](const DNSResponse& dnsQuestion) -> ComboAddress { return dnsQuestion.ids.origRemote; }, [](DNSResponse& dnsQuestion, const ComboAddress newRemote) { (void)dnsQuestion; (void)newRemote; });
luaCtx.registerMember<dnsheader*(DNSResponse::*)>(
"dh",
[](const DNSResponse& dnsResponse) -> dnsheader* {
luaCtx.registerMember<uint16_t(DNSResponse::*)>(
"len", [](const DNSResponse& dnsQuestion) -> uint16_t { return dnsQuestion.getData().size(); }, [](DNSResponse& dnsQuestion, uint16_t newlen) { dnsQuestion.getMutableData().resize(newlen); });
luaCtx.registerMember<uint8_t(DNSResponse::*)>(
- "opcode", [](const DNSResponse& dnsQuestion) -> uint8_t { return dnsQuestion.getHeader()->opcode; }, [](DNSResponse& dnsQuestion, uint8_t newOpcode) { (void)newOpcode; });
+ "opcode", [](const DNSResponse& dnsQuestion) -> uint8_t { return dnsQuestion.getHeader()->opcode; }, [](DNSResponse& dnsQuestion, uint8_t newOpcode) { (void)dnsQuestion; (void)newOpcode; });
luaCtx.registerMember<bool(DNSResponse::*)>(
- "tcp", [](const DNSResponse& dnsQuestion) -> bool { return dnsQuestion.overTCP(); }, [](DNSResponse& dnsQuestion, bool newTcp) { (void)newTcp; });
+ "tcp", [](const DNSResponse& dnsQuestion) -> bool { return dnsQuestion.overTCP(); }, [](DNSResponse& dnsQuestion, bool newTcp) { (void)dnsQuestion; (void)newTcp; });
luaCtx.registerMember<bool(DNSResponse::*)>(
"skipCache", [](const DNSResponse& dnsQuestion) -> bool { return dnsQuestion.ids.skipCache; }, [](DNSResponse& dnsQuestion, bool newSkipCache) { dnsQuestion.ids.skipCache = newSkipCache; });
luaCtx.registerMember<std::string(DNSResponse::*)>(
size_t dnsdist_ffi_servers_list_chashed(const dnsdist_ffi_servers_list_t* list, const dnsdist_ffi_dnsquestion_t* dq, size_t hash)
{
+ (void)dq;
auto server = chashedFromHash(list->servers, hash);
return dnsdist_ffi_servers_get_index_from_server(list->servers, server);
}
size_t dnsdist_ffi_servers_list_whashed(const dnsdist_ffi_servers_list_t* list, const dnsdist_ffi_dnsquestion_t* dq, size_t hash)
{
+ (void)dq;
auto server = whashedFromHash(list->servers, hash);
return dnsdist_ffi_servers_get_index_from_server(list->servers, server);
}
double dnsdist_ffi_metric_get(const char* metricName, size_t metricNameLen, bool isCounter)
{
+ (void)isCounter;
auto result = dnsdist::metrics::getCustomMetric(std::string_view(metricName, metricNameLen), {});
if (std::get_if<dnsdist::metrics::Error>(&result) != nullptr) {
return 0.;
static void setTicketsKeyAddedHook(const LuaContext& context, const TicketsKeyAddedHook& hook)
{
+ (void)context;
TLSCtx::setTicketsKeyAddedHook([hook](const std::string& key) {
try {
auto lua = g_lua.lock();
nowRealTime.tv_nsec -= 1000000000;
}
- return nowRealTime; }, [](DynBlock& block, [[maybe_unused]] timespec until) {});
+ return nowRealTime; }, []([[maybe_unused]] DynBlock& block, [[maybe_unused]] timespec until) {});
luaCtx.registerMember<DynBlock, unsigned int>(
- "blocks", [](const DynBlock& block) { return block.blocks.load(); }, [](DynBlock& block, [[maybe_unused]] unsigned int blocks) {});
+ "blocks", [](const DynBlock& block) { return block.blocks.load(); }, []([[maybe_unused]] DynBlock& block, [[maybe_unused]] unsigned int blocks) {});
luaCtx.registerMember("action", &DynBlock::action);
luaCtx.registerMember("warning", &DynBlock::warning);
luaCtx.registerMember("bpf", &DynBlock::bpf);
dnsdist::webserver::registerWebHandler(path, [handler](const YaHTTP::Request& req, YaHTTP::Response& resp) { handler(&req, &resp); }, true);
});
- luaCtx.registerMember<std::string(YaHTTP::Request::*)>("path", [](const YaHTTP::Request& req) -> std::string { return req.url.path; }, [](YaHTTP::Request& req, const std::string& path) { (void) path; });
- luaCtx.registerMember<int(YaHTTP::Request::*)>("version", [](const YaHTTP::Request& req) -> int { return req.version; }, [](YaHTTP::Request& req, int version) { (void) version; });
- luaCtx.registerMember<std::string(YaHTTP::Request::*)>("method", [](const YaHTTP::Request& req) -> std::string { return req.method; }, [](YaHTTP::Request& req, const std::string& method) { (void) method; });
- luaCtx.registerMember<std::string(YaHTTP::Request::*)>("body", [](const YaHTTP::Request& req) -> const std::string { return req.body; }, [](YaHTTP::Request& req, const std::string& body) { (void) body; });
+ luaCtx.registerMember<std::string(YaHTTP::Request::*)>("path", [](const YaHTTP::Request& req) -> std::string { return req.url.path; }, [](YaHTTP::Request& req, const std::string& path) { (void)req; (void) path; });
+ luaCtx.registerMember<int(YaHTTP::Request::*)>("version", [](const YaHTTP::Request& req) -> int { return req.version; }, [](YaHTTP::Request& req, int version) { (void)req; (void)version; });
+ luaCtx.registerMember<std::string(YaHTTP::Request::*)>("method", [](const YaHTTP::Request& req) -> std::string { return req.method; }, [](YaHTTP::Request& req, const std::string& method) { (void)req; (void) method; });
+ luaCtx.registerMember<std::string(YaHTTP::Request::*)>("body", [](const YaHTTP::Request& req) -> const std::string { return req.body; }, [](YaHTTP::Request& req, const std::string& body) { (void)req; (void)body; });
luaCtx.registerMember<LuaAssociativeTable<std::string>(YaHTTP::Request::*)>("getvars", [](const YaHTTP::Request& req) {
LuaAssociativeTable<std::string> values;
for (const auto& entry : req.getvars) {
values.insert({entry.first, entry.second});
}
return values;
- }, [](YaHTTP::Request& req, const LuaAssociativeTable<std::string>& values) { (void) values; });
+ }, [](YaHTTP::Request& req, const LuaAssociativeTable<std::string>& values) { (void)req; (void)values; });
luaCtx.registerMember<LuaAssociativeTable<std::string>(YaHTTP::Request::*)>("postvars", [](const YaHTTP::Request& req) {
LuaAssociativeTable<std::string> values;
for (const auto& entry : req.postvars) {
values.insert({entry.first, entry.second});
}
return values;
- }, [](YaHTTP::Request& req, const LuaAssociativeTable<std::string>& values) { (void) values; });
+ }, [](YaHTTP::Request& req, const LuaAssociativeTable<std::string>& values) { (void)req; (void)values; });
luaCtx.registerMember<LuaAssociativeTable<std::string>(YaHTTP::Request::*)>("headers", [](const YaHTTP::Request& req) {
LuaAssociativeTable<std::string> values;
for (const auto& entry : req.headers) {
values.insert({entry.first, entry.second});
}
return values;
- }, [](YaHTTP::Request& req, const LuaAssociativeTable<std::string>& values) { (void) values; });
+ }, [](YaHTTP::Request& req, const LuaAssociativeTable<std::string>& values) { (void)req; (void)values; });
/* Response */
luaCtx.registerMember<std::string(YaHTTP::Response::*)>("body", [](const YaHTTP::Response& resp) -> const std::string { return resp.body; }, [](YaHTTP::Response& resp, const std::string& body) { resp.body = body; });
ssize_t IncomingHTTP2Connection::send_callback(nghttp2_session* session, const uint8_t* data, size_t length, int flags, void* user_data)
{
+ (void)session;
+ (void)flags;
auto* conn = static_cast<IncomingHTTP2Connection*>(user_data);
if (conn->d_connectionDied) {
return static_cast<ssize_t>(length);
IOState IncomingHTTP2Connection::sendResponse(const struct timeval& now, TCPResponse&& response)
{
+ (void)now;
if (response.d_idstate.d_streamID == -1) {
throw std::runtime_error("Invalid DoH stream ID while sending response");
}
data_provider.source.ptr = this;
data_provider.read_callback = [](nghttp2_session*, IncomingHTTP2Connection::StreamID stream_id, uint8_t* buf, size_t length, uint32_t* data_flags, nghttp2_data_source* source, void* cb_data) -> ssize_t {
+ (void)source;
auto* connection = static_cast<IncomingHTTP2Connection*>(cb_data);
auto& obj = connection->d_currentStreams.at(stream_id);
size_t toCopy = 0;
int IncomingHTTP2Connection::on_frame_recv_callback(nghttp2_session* session, const nghttp2_frame* frame, void* user_data)
{
+ (void)session;
auto* conn = static_cast<IncomingHTTP2Connection*>(user_data);
/* is this the last frame for this stream? */
if ((frame->hd.type == NGHTTP2_HEADERS || frame->hd.type == NGHTTP2_DATA) && (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) != 0) {
int IncomingHTTP2Connection::on_stream_close_callback(nghttp2_session* session, IncomingHTTP2Connection::StreamID stream_id, uint32_t error_code, void* user_data)
{
+ (void)session;
+ (void)error_code;
auto* conn = static_cast<IncomingHTTP2Connection*>(user_data);
conn->d_currentStreams.erase(stream_id);
int IncomingHTTP2Connection::on_begin_headers_callback(nghttp2_session* session, const nghttp2_frame* frame, void* user_data)
{
+ (void)session;
if (frame->hd.type != NGHTTP2_HEADERS || frame->headers.cat != NGHTTP2_HCAT_REQUEST) {
return 0;
}
int IncomingHTTP2Connection::on_header_callback(nghttp2_session* session, const nghttp2_frame* frame, const uint8_t* name, size_t nameLen, const uint8_t* value, size_t valuelen, uint8_t flags, void* user_data)
{
+ (void)session;
+ (void)flags;
auto* conn = static_cast<IncomingHTTP2Connection*>(user_data);
if (frame->hd.type == NGHTTP2_HEADERS && frame->headers.cat == NGHTTP2_HCAT_REQUEST) {
int IncomingHTTP2Connection::on_data_chunk_recv_callback(nghttp2_session* session, uint8_t flags, IncomingHTTP2Connection::StreamID stream_id, const uint8_t* data, size_t len, void* user_data)
{
+ (void)session;
+ (void)flags;
auto* conn = static_cast<IncomingHTTP2Connection*>(user_data);
auto stream = conn->d_currentStreams.find(stream_id);
if (stream == conn->d_currentStreams.end()) {
int IncomingHTTP2Connection::on_error_callback(nghttp2_session* session, int lib_error_code, const char* msg, size_t len, void* user_data)
{
+ (void)session;
auto* conn = static_cast<IncomingHTTP2Connection*>(user_data);
- vinfolog("Error in HTTP/2 connection from %d: %s", conn->d_ci.remote.toStringWithPort(), std::string(msg, len));
+ vinfolog("Error in HTTP/2 connection from %s: %s (%d)", conn->d_ci.remote.toStringWithPort(), std::string(msg, len), lib_error_code);
conn->d_connectionClosing = true;
conn->d_needFlush = true;
nghttp2_session_terminate_session(conn->d_session.get(), NGHTTP2_NO_ERROR);
void DoHConnectionToBackend::handleTimeout(const struct timeval& now, bool write)
{
+ (void)now;
if (write) {
if (d_firstWrite) {
++d_ds->tcpConnectTimeouts;
data_provider.source.ptr = this;
data_provider.read_callback = [](nghttp2_session* session, int32_t stream_id, uint8_t* buf, size_t length, uint32_t* data_flags, nghttp2_data_source* source, void* user_data) -> ssize_t {
+ (void)session;
+ (void)source;
auto* conn = static_cast<DoHConnectionToBackend*>(user_data);
auto& request = conn->d_currentStreams.at(stream_id);
size_t toCopy = 0;
ssize_t DoHConnectionToBackend::send_callback(nghttp2_session* session, const uint8_t* data, size_t length, int flags, void* user_data)
{
+ (void)session;
+ (void)flags;
DoHConnectionToBackend* conn = reinterpret_cast<DoHConnectionToBackend*>(user_data);
bool bufferWasEmpty = conn->d_out.empty();
if (!conn->d_proxyProtocolPayloadSent && !conn->d_proxyProtocolPayload.empty()) {
int DoHConnectionToBackend::on_frame_recv_callback(nghttp2_session* session, const nghttp2_frame* frame, void* user_data)
{
+ (void)session;
DoHConnectionToBackend* conn = reinterpret_cast<DoHConnectionToBackend*>(user_data);
// cerr<<"Frame type is "<<std::to_string(frame->hd.type)<<endl;
#if 0
int DoHConnectionToBackend::on_data_chunk_recv_callback(nghttp2_session* session, uint8_t flags, int32_t stream_id, const uint8_t* data, size_t len, void* user_data)
{
+ (void)session;
+ (void)flags;
DoHConnectionToBackend* conn = reinterpret_cast<DoHConnectionToBackend*>(user_data);
// cerr<<"Got data of size "<<len<<" for stream "<<stream_id<<endl;
auto stream = conn->d_currentStreams.find(stream_id);
int DoHConnectionToBackend::on_stream_close_callback(nghttp2_session* session, int32_t stream_id, uint32_t error_code, void* user_data)
{
+ (void)session;
DoHConnectionToBackend* conn = reinterpret_cast<DoHConnectionToBackend*>(user_data);
if (error_code == 0) {
int DoHConnectionToBackend::on_header_callback(nghttp2_session* session, const nghttp2_frame* frame, const uint8_t* name, size_t namelen, const uint8_t* value, size_t valuelen, uint8_t flags, void* user_data)
{
+ (void)session;
+ (void)flags;
DoHConnectionToBackend* conn = reinterpret_cast<DoHConnectionToBackend*>(user_data);
const std::string status(":status");
int DoHConnectionToBackend::on_error_callback(nghttp2_session* session, int lib_error_code, const char* msg, size_t len, void* user_data)
{
- vinfolog("Error in HTTP/2 connection: %s", std::string(msg, len));
+ (void)session;
+ vinfolog("Error in HTTP/2 connection: %s (%d)", std::string(msg, len), lib_error_code);
DoHConnectionToBackend* conn = reinterpret_cast<DoHConnectionToBackend*>(user_data);
conn->d_connectionDied = true;
static void handleCrossProtocolQuery(int pipefd, FDMultiplexer::funcparam_t& param)
{
+ (void)pipefd;
auto threadData = boost::any_cast<DoHClientThreadData*>(param);
std::unique_ptr<CrossProtocolQuery> cpq{nullptr};
netsnmp_agent_request_info* reqinfo,
netsnmp_request_info* requests)
{
+ (void)handler;
if (reqinfo->mode != MODE_GET) {
return SNMP_ERR_GENERR;
}
netsnmp_agent_request_info* reqinfo,
netsnmp_request_info* requests)
{
+ (void)handler;
if (reqinfo->mode != MODE_GET) {
return SNMP_ERR_GENERR;
}
netsnmp_agent_request_info* reqinfo,
netsnmp_request_info* requests)
{
+ (void)handler;
if (reqinfo->mode != MODE_GET) {
return SNMP_ERR_GENERR;
}
netsnmp_variable_list* put_index_data,
netsnmp_iterator_info* mydata)
{
+ (void)loop_context;
+ (void)mydata;
if (s_currentServerIdx >= s_servers.size()) {
return nullptr;
}
netsnmp_agent_request_info* reqinfo,
netsnmp_request_info* requests)
{
+ (void)handler;
+ (void)reginfo;
netsnmp_request_info* request{nullptr};
switch (reqinfo->mode) {
memcpy(&payload.at(startOfHeaderOffset), &id, sizeof(id));
}
-enum class QueryState : uint8_t {
- hasSizePrepended,
- noSize
-};
-
enum class ConnectionState : uint8_t {
needProxy,
proxySent
};
-static void prepareQueryForSending(TCPQuery& query, uint16_t id, QueryState queryState, ConnectionState connectionState)
+static void prepareQueryForSending(TCPQuery& query, uint16_t id, ConnectionState connectionState)
{
if (connectionState == ConnectionState::needProxy) {
if (query.d_proxyProtocolPayload.size() > 0 && !query.d_proxyProtocolPayloadAdded) {
conn->d_currentQuery = std::move(conn->d_pendingQueries.front());
uint16_t id = conn->d_highestStreamID;
- prepareQueryForSending(conn->d_currentQuery.d_query, id, QueryState::hasSizePrepended, conn->needProxyProtocolPayload() ? ConnectionState::needProxy : ConnectionState::proxySent);
+ prepareQueryForSending(conn->d_currentQuery.d_query, id, conn->needProxyProtocolPayload() ? ConnectionState::needProxy : ConnectionState::proxySent);
conn->d_pendingQueries.pop_front();
conn->d_state = State::sendingQueryToBackend;
IOState TCPConnectionToBackend::sendQuery(std::shared_ptr<TCPConnectionToBackend>& conn, const struct timeval& now)
{
+ (void)now;
DEBUGLOG("sending query to backend "<<conn->getDS()->getNameWithAddr()<<" over FD "<<conn->d_handler->getDescriptor());
IOState state = conn->d_handler->tryWrite(conn->d_currentQuery.d_query.d_buffer, conn->d_currentPos, conn->d_currentQuery.d_query.d_buffer.size());
/* we need to edit this query so it has the correct ID */
auto query = std::move(conn->d_currentQuery);
uint16_t id = conn->d_highestStreamID;
- prepareQueryForSending(query.d_query, id, QueryState::hasSizePrepended, ConnectionState::needProxy);
+ prepareQueryForSending(query.d_query, id, ConnectionState::needProxy);
conn->d_currentQuery = std::move(query);
}
uint16_t id = d_highestStreamID;
d_currentQuery = PendingRequest({sender, std::move(query)});
- prepareQueryForSending(d_currentQuery.d_query, id, QueryState::hasSizePrepended, needProxyProtocolPayload() ? ConnectionState::needProxy : ConnectionState::proxySent);
+ prepareQueryForSending(d_currentQuery.d_query, id, needProxyProtocolPayload() ? ConnectionState::needProxy : ConnectionState::proxySent);
struct timeval now;
gettimeofday(&now, 0);
}
virtual std::unique_ptr<DOHUnitInterface> getDOHUnit(uint32_t streamID)
{
+ (void)streamID;
throw std::runtime_error("Getting a DOHUnit state from a generic TCP/DoT connection is not supported");
}
virtual void restoreDOHUnit(std::unique_ptr<DOHUnitInterface>&&)
/* called when the buffer has been set and the rules have been processed, and only from handleIO (sometimes indirectly via handleQuery) */
IOState IncomingTCPConnectionState::sendResponse(const struct timeval& now, TCPResponse&& response)
{
+ (void)now;
d_state = State::sendingResponse;
const auto responseSize = static_cast<uint16_t>(response.d_buffer.size());
}
}
-static bool processXFRResponse(PacketBuffer& response, DNSResponse& dnsResponse)
+static bool processXFRResponse(DNSResponse& dnsResponse)
{
const auto& chains = dnsdist::configuration::getCurrentRuntimeConfiguration().d_ruleChains;
const auto& xfrRespRuleActions = dnsdist::rules::getResponseRuleChain(chains, dnsdist::rules::ResponseRuleChain::XFRResponseRules);
dnsResponse.d_incomingTCPState = state;
memcpy(&response.d_cleartextDH, dnsResponse.getHeader().get(), sizeof(response.d_cleartextDH));
- if (!processXFRResponse(response.d_buffer, dnsResponse)) {
+ if (!processXFRResponse(dnsResponse)) {
state->terminateClientConnection();
return;
}
static void handleIncomingTCPQuery(int pipefd, FDMultiplexer::funcparam_t& param)
{
+ (void)pipefd;
auto* threadData = boost::any_cast<TCPClientThreadData*>(param);
std::unique_ptr<ConnectionInfo> citmp{nullptr};
static void handleCrossProtocolQuery(int pipefd, FDMultiplexer::funcparam_t& param)
{
+ (void)pipefd;
auto* threadData = boost::any_cast<TCPClientThreadData*>(param);
std::unique_ptr<CrossProtocolQuery> cpq{nullptr};
static void handleCrossProtocolResponse(int pipefd, FDMultiplexer::funcparam_t& param)
{
+ (void)pipefd;
auto* threadData = boost::any_cast<TCPClientThreadData*>(param);
std::unique_ptr<TCPCrossProtocolResponse> cpr{nullptr};
}
auto acceptCallback = [&data](int socket, FDMultiplexer::funcparam_t& funcparam) {
+ (void)socket;
const auto* acceptorParam = boost::any_cast<const TCPAcceptorParam*>(funcparam);
acceptNewConnection(*acceptorParam, &data);
};
}
else {
auto acceptCallback = [](int socket, FDMultiplexer::funcparam_t& funcparam) {
+ (void)socket;
const auto* acceptorParam = boost::any_cast<const TCPAcceptorParam*>(funcparam);
acceptNewConnection(*acceptorParam, nullptr);
};
#ifndef DISABLE_BUILTIN_HTML
#include "htmlfiles.h"
-static void redirectToIndex(const YaHTTP::Request& req, YaHTTP::Response& resp)
+static void redirectToIndex([[maybe_unused]] const YaHTTP::Request& req, YaHTTP::Response& resp)
{
const string charset = "; charset=utf-8";
resp.body.assign(s_urlmap.at("index.html"));
}
#if !defined(DISABLE_RECVMMSG) && defined(HAVE_RECVMMSG) && defined(HAVE_SENDMMSG) && defined(MSG_WAITFORONE)
-static void queueResponse(const ClientState& clientState, const PacketBuffer& response, const ComboAddress& dest, const ComboAddress& remote, struct mmsghdr& outMsg, struct iovec* iov, cmsgbuf_aligned* cbuf)
+static void queueResponse(const PacketBuffer& response, const ComboAddress& dest, const ComboAddress& remote, struct mmsghdr& outMsg, struct iovec* iov, cmsgbuf_aligned* cbuf)
{
outMsg.msg_len = 0;
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast,cppcoreguidelines-pro-type-reinterpret-cast): API
void handleResponse(const struct timeval& now, TCPResponse&& response) override
{
+ (void)now;
if (!response.d_ds && !response.d_idstate.selfGenerated) {
throw std::runtime_error("Passing a cross-protocol answer originated from UDP without a valid downstream");
}
#ifndef DISABLE_RECVMMSG
#if defined(HAVE_RECVMMSG) && defined(HAVE_SENDMMSG) && defined(MSG_WAITFORONE)
if (dnsQuestion.ids.delayMsec == 0 && responsesVect != nullptr) {
- queueResponse(clientState, query, dest, remote, (*responsesVect)[*queuedResponses], respIOV, respCBuf);
+ queueResponse(query, dest, remote, (*responsesVect)[*queuedResponses], respIOV, respCBuf);
(*queuedResponses)++;
handleResponseSent(dnsQuestion.ids.qname, dnsQuestion.ids.qtype, 0., remote, ComboAddress(), query.size(), *dnsHeader, dnsdist::Protocol::DoUDP, dnsdist::Protocol::DoUDP, false);
return;
}
else {
auto callback = [&remote, &msgh, &iov, &packet, &handleOnePacket, initialBufferSize](int socket, FDMultiplexer::funcparam_t& funcparam) {
+ (void)socket;
const auto* param = boost::any_cast<const UDPStateParam*>(funcparam);
try {
remote.sin4.sin_family = param->cs->local.sin4.sin_family;
}
}
-static void bindAny(int addressFamily, int sock)
+static void bindAny([[maybe_unused]] int addressFamily, int sock)
{
__attribute__((unused)) int one = 1;
void handleResponse(const struct timeval& now, TCPResponse&& response) override
{
+ (void)now;
if (!response.d_idstate.du) {
return;
}
void notifyIOError(const struct timeval& now, TCPResponse&& response) override
{
+ (void)now;
auto& query = response.d_idstate;
if (!query.du) {
return;
/* called when a HTTP response is about to be sent, from the main DoH thread */
static void on_response_ready_cb(struct st_h2o_filter_t *self, h2o_req_t *req, h2o_ostream_t **slot)
{
+ (void)self;
if (req == nullptr) {
return;
}
*/
static void on_dnsdist(h2o_socket_t *listener, const char *err)
{
+ (void)err;
/* we want to read as many responses from the pipe as possible before
giving up. Even if we are overloaded and fighting with the DoH connections
for the CPU, the first thing we need to do is to send responses to free slots
handleImmediateError("Unsupported HTTP method");
}
-static void processH3DataEvent(ClientState& clientState, DOH3Frontend& frontend, H3Connection& conn, const ComboAddress& client, const PacketBuffer& serverConnID, const uint64_t streamID, quiche_h3_event* event, PacketBuffer& buffer)
+static void processH3DataEvent(ClientState& clientState, DOH3Frontend& frontend, H3Connection& conn, const ComboAddress& client, const PacketBuffer& serverConnID, const uint64_t streamID, PacketBuffer& buffer)
{
auto handleImmediateError = [&clientState, &frontend, &conn, streamID](const char* msg) {
DEBUGLOG(msg);
break;
}
case QUICHE_H3_EVENT_DATA: {
- processH3DataEvent(clientState, frontend, conn, client, serverConnID, streamID, event, buffer);
+ processH3DataEvent(clientState, frontend, conn, client, serverConnID, streamID, buffer);
break;
}
case QUICHE_H3_EVENT_FINISHED:
{
}
- void release(bool removeFomCache)
+ void release(bool removeFromCache)
{
+ (void)removeFromCache;
}
std::shared_ptr<DownstreamState> getDS() const
bool dnsdist::webserver::addMetricDefinition(const dnsdist::prometheus::PrometheusMetricDefinition& def)
{
+ (void)def;
return true;
}
ProcessQueryResult processQueryAfterRules(DNSQuestion& dnsQuestion, std::shared_ptr<DownstreamState>& selectedBackend)
{
+ (void)dnsQuestion;
+ (void)selectedBackend;
return ProcessQueryResult::Drop;
}
bool processResponseAfterRules(PacketBuffer& response, DNSResponse& dnsResponse, bool muted)
{
+ (void)response;
+ (void)dnsResponse;
+ (void)muted;
return false;
}
bool applyRulesToResponse(const std::vector<dnsdist::rules::ResponseRuleAction>& respRuleActions, DNSResponse& dnsResponse)
{
+ (void)respRuleActions;
+ (void)dnsResponse;
return true;
}
bool sendUDPResponse(int origFD, const PacketBuffer& response, const int delayMsec, const ComboAddress& origDest, const ComboAddress& origRemote)
{
+ (void)origFD;
+ (void)response;
+ (void)delayMsec;
+ (void)origDest;
+ (void)origRemote;
return false;
}
bool assignOutgoingUDPQueryToBackend(std::shared_ptr<DownstreamState>& downstream, uint16_t queryID, DNSQuestion& dnsQuestion, PacketBuffer& query, bool actuallySend)
{
+ (void)downstream;
+ (void)queryID;
+ (void)dnsQuestion;
+ (void)query;
+ (void)actuallySend;
return true;
}
{
std::unique_ptr<CrossProtocolQuery> getInternalQueryFromDQ(DNSQuestion& dnsQuestion, bool isResponse)
{
+ (void)dnsQuestion;
+ (void)isResponse;
return nullptr;
}
}
{
bool XskProcessQuery(ClientState& clientState, XskPacket& packet)
{
+ (void)clientState;
+ (void)packet;
return false;
}
}
bool processResponderPacket(std::shared_ptr<DownstreamState>& dss, PacketBuffer& response, InternalQueryState&& ids)
{
+ (void)dss;
+ (void)response;
+ (void)ids;
return false;
}
{
DynBlockRulesGroup::DynBlockRule rule(reason, blockDuration, 0, 0, numberOfSeconds, action);
dbrg.setSuffixMatchRule(std::move(rule), [](const StatNode& node, const StatNode::Stat& self, const StatNode::Stat& children) {
+ (void)node;
+ (void)children;
if (self.queries > 0) {
return std::tuple<bool, boost::optional<std::string>, boost::optional<int>>(true, boost::none, boost::none);
}
{
DynBlockRulesGroup::DynBlockRule rule(reason, blockDuration, 0, 0, numberOfSeconds, action);
dbrg.setSuffixMatchRule(std::move(rule), [](const StatNode& node, const StatNode::Stat& self, const StatNode::Stat& children) {
+ (void)node;
+ (void)children;
if (self.queries > 0) {
return std::tuple<bool, boost::optional<std::string>, boost::optional<int>>(true, "blocked for a different reason", static_cast<int>(DNSAction::Action::Truncate));
}
// NOLINTNEXTLINE(readability-convert-member-functions-to-static): this is a stub, the real one is not that simple..
bool DNSDistSNMPAgent::sendDNSTrap(const DNSQuestion& dnsQuestion, const std::string& reason)
{
+ (void)dnsQuestion;
+ (void)reason;
return false;
}
// NOLINTNEXTLINE(performance-unnecessary-value-param): this is a stub, the real one is not that simple and the performance does not matter
void responderThread(std::shared_ptr<DownstreamState> dss)
{
+ (void)dss;
}
string g_outputBuffer;
}
}
cerr << pol.name << " took " << std::to_string(sw.udiff()) << " us for " << names.size() << endl;
+#else
+ (void)pol;
#endif /* BENCH_POLICIES */
}
BOOST_REQUIRE(fd >= 0);
listener.addUnixListeningEndpoint(socketPath, 0, [&received, payload](dnsdist::NetworkListener::EndpointID endpoint, std::string&& dgram, const std::string& from) {
+ (void)from;
BOOST_CHECK_EQUAL(endpoint, 0U);
BOOST_CHECK(dgram == payload);
received = true;
/* invalid path */
dnsdist::NetworkListener listener;
BOOST_CHECK_THROW(listener.addUnixListeningEndpoint(std::string(), 0,
- [](dnsdist::NetworkListener::EndpointID endpoint, std::string&& dgram, const std::string& from) {}),
+ [](dnsdist::NetworkListener::EndpointID endpoint, std::string&& dgram, const std::string& from) {
+ (void)endpoint;
+ (void)dgram;
+ (void)from;
+ }),
std::runtime_error);
bool caught = false;
dnsdist::NetworkListener listener;
bool received = false;
listener.addUnixListeningEndpoint(socketPath, 0, [&received](dnsdist::NetworkListener::EndpointID endpoint, std::string&& dgram, const std::string& from) {
+ (void)endpoint;
+ (void)dgram;
+ (void)from;
received = true;
});
bool raised = false;
try {
listener.addUnixListeningEndpoint(otherSocketPath, 0,
- [](dnsdist::NetworkListener::EndpointID endpoint, std::string&& dgram, const std::string& from) {});
+ [](dnsdist::NetworkListener::EndpointID endpoint, std::string&& dgram, const std::string& from) {
+ (void)endpoint;
+ (void)dgram;
+ (void)from;
+ });
}
catch (const std::runtime_error& e) {
raised = true;
dnsdist::NetworkListener listener;
bool received = false;
listener.addUnixListeningEndpoint(socketPath, 0, [&received](dnsdist::NetworkListener::EndpointID endpoint, std::string&& dgram, const std::string& from) {
+ (void)endpoint;
+ (void)dgram;
+ (void)from;
received = true;
throw std::runtime_error("Test exception");
});
dnsdist::NetworkListener listener;
bool received = false;
listener.addUnixListeningEndpoint(socketPath, 0, [&received](dnsdist::NetworkListener::EndpointID endpoint, std::string&& dgram, const std::string& from) {
+ (void)endpoint;
+ (void)dgram;
+ (void)from;
received = true;
throw UnexpectedException();
});
socketPath.insert(0, 1, 0);
listener.addUnixListeningEndpoint(socketPath, 0, [&received, payload](dnsdist::NetworkListener::EndpointID endpoint, std::string&& dgram, const std::string& from) {
+ (void)from;
BOOST_CHECK_EQUAL(endpoint, 0U);
BOOST_CHECK(dgram == payload);
received = true;
socketPath.insert(0, 1, 0);
bool received = false;
listener.addUnixListeningEndpoint(socketPath, 0, [&received](dnsdist::NetworkListener::EndpointID endpoint, std::string&& dgram, const std::string& from) {
+ (void)endpoint;
+ (void)dgram;
+ (void)from;
received = true;
});
/* try binding twice to the same path */
bool raised = false;
try {
- listener.addUnixListeningEndpoint(socketPath, 0, [](dnsdist::NetworkListener::EndpointID endpoint, std::string&& dgram, const std::string& from) {});
+ listener.addUnixListeningEndpoint(socketPath, 0, [](dnsdist::NetworkListener::EndpointID endpoint, std::string&& dgram, const std::string& from) {
+ (void)endpoint;
+ (void)dgram;
+ (void)from;
+ });
}
catch (const std::runtime_error& e) {
raised = true;
nghttp2_data_provider data_provider;
data_provider.source.ptr = this;
data_provider.read_callback = [](nghttp2_session* session, int32_t stream_id, uint8_t* buf, size_t length, uint32_t* data_flags, nghttp2_data_source* source, void* user_data) -> ssize_t {
+ (void)session;
+ (void)stream_id;
+ (void)source;
auto* conn = static_cast<DOHConnection*>(user_data);
auto& pos = conn->d_position;
const auto& currentQuery = conn->d_currentQuery;
private:
static ssize_t send_callback(nghttp2_session* session, const uint8_t* data, size_t length, int flags, void* user_data)
{
+ (void)session;
+ (void)flags;
auto* conn = static_cast<DOHConnection*>(user_data);
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic): nghttp2 API
conn->d_clientOutBuffer.insert(conn->d_clientOutBuffer.end(), data, data + length);
static int on_frame_recv_callback(nghttp2_session* session, const nghttp2_frame* frame, void* user_data)
{
+ (void)session;
auto* conn = static_cast<DOHConnection*>(user_data);
if ((frame->hd.type == NGHTTP2_HEADERS || frame->hd.type == NGHTTP2_DATA) && (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) != 0) {
const auto& response = conn->d_responses.at(frame->hd.stream_id);
static int on_data_chunk_recv_callback(nghttp2_session* session, uint8_t flags, int32_t stream_id, const uint8_t* data, size_t len, void* user_data)
{
+ (void)session;
+ (void)flags;
auto* conn = static_cast<DOHConnection*>(user_data);
auto& response = conn->d_responses[stream_id];
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic): nghttp2 API
static int on_header_callback(nghttp2_session* session, const nghttp2_frame* frame, const uint8_t* name, size_t namelen, const uint8_t* value, size_t valuelen, uint8_t flags, void* user_data)
{
+ (void)session;
+ (void)flags;
auto* conn = static_cast<DOHConnection*>(user_data);
const std::string status(":status");
if (frame->hd.type == NGHTTP2_HEADERS && frame->headers.cat == NGHTTP2_HCAT_RESPONSE) {
static int on_stream_close_callback(nghttp2_session* session, int32_t stream_id, uint32_t error_code, void* user_data)
{
+ (void)session;
+ (void)stream_id;
+ (void)error_code;
+ (void)user_data;
return 0;
}
};
IOState tryConnect(bool fastOpen, const ComboAddress& remote) override
{
+ (void)fastOpen;
+ (void)remote;
throw std::runtime_error("Should not happen");
}
void setSession(std::unique_ptr<TLSSession>& session) override
{
+ (void)session;
}
[[nodiscard]] std::vector<int> getAsyncFDs() override
void connect(bool fastOpen, const ComboAddress& remote, const struct timeval& timeout) override
{
+ (void)fastOpen;
+ (void)remote;
+ (void)timeout;
}
size_t read(void* buffer, size_t bufferSize, const struct timeval& readTimeout, const struct timeval& totalTimeout = {0, 0}, bool allowIncomplete = false) override
{
+ (void)buffer;
+ (void)bufferSize;
+ (void)readTimeout;
+ (void)totalTimeout;
+ (void)allowIncomplete;
return 0;
}
size_t write(const void* buffer, size_t bufferSize, const struct timeval& writeTimeout) override
{
+ (void)buffer;
+ (void)bufferSize;
+ (void)writeTimeout;
return 0;
}
{
/* dnsdist sends a response right away, client closes the connection after getting the response */
s_processQuery = [response](DNSQuestion& dnsQuestion, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
+ (void)selectedBackend;
/* self answered */
dnsQuestion.getMutableData() = response;
return ProcessQueryResult::SendAnswer;
{
/* dnsdist sends a response right away, but the client closes the connection without even reading the response */
s_processQuery = [response](DNSQuestion& dnsQuestion, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
+ (void)selectedBackend;
/* self answered */
dnsQuestion.getMutableData() = response;
return ProcessQueryResult::SendAnswer;
{
/* dnsdist sends a response right away, client closes the connection while getting the response */
s_processQuery = [response](DNSQuestion& dnsQuestion, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
+ (void)selectedBackend;
/* self answered */
dnsQuestion.getMutableData() = response;
return ProcessQueryResult::SendAnswer;
auto backend = std::make_shared<DownstreamState>(getBackendAddress("42", 53));
- struct timeval now
- {
- };
+ timeval now{};
gettimeofday(&now, nullptr);
size_t counter = 0;
{
/* dnsdist forwards the query to the backend, which does not answer -> timeout */
s_processQuery = [backend](DNSQuestion& dnsQuestion, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
+ (void)dnsQuestion;
selectedBackend = backend;
return ProcessQueryResult::PassToBackend;
};
nghttp2_data_provider dataProvider;
dataProvider.source.ptr = &data;
dataProvider.read_callback = [](nghttp2_session* session, int32_t stream_id, uint8_t* buf, size_t length, uint32_t* data_flags, nghttp2_data_source* source, void* user_data) -> ssize_t {
+ (void)session;
+ (void)stream_id;
+ (void)user_data;
auto buffer = reinterpret_cast<PacketBuffer*>(source->ptr);
size_t toCopy = 0;
if (buffer->size() > 0) {
void submitError(uint32_t streamId, uint16_t status, const std::string& msg)
{
+ (void)msg;
const std::string statusStr = std::to_string(status);
const nghttp2_nv hdrs[] = {{(uint8_t*)":status", (uint8_t*)statusStr.c_str(), sizeof(":status") - 1, statusStr.size(), NGHTTP2_NV_FLAG_NONE}};
private:
static ssize_t send_callback(nghttp2_session* session, const uint8_t* data, size_t length, int flags, void* user_data)
{
+ (void)session;
+ (void)flags;
DOHConnection* conn = reinterpret_cast<DOHConnection*>(user_data);
// cerr<<"inserting "<<length<<" bytes into the server output buffer of size "<<conn->d_serverOutBuffer.size()<<endl;
if (!conn->d_idMapping.empty() && length > 9) {
static int on_frame_recv_callback(nghttp2_session* session, const nghttp2_frame* frame, void* user_data)
{
+ (void)session;
DOHConnection* conn = reinterpret_cast<DOHConnection*>(user_data);
// cerr<<"Frame type is "<<std::to_string(frame->hd.type)<<endl;
if ((frame->hd.type == NGHTTP2_HEADERS || frame->hd.type == NGHTTP2_DATA) && frame->hd.flags & NGHTTP2_FLAG_END_STREAM) {
static int on_data_chunk_recv_callback(nghttp2_session* session, uint8_t flags, int32_t stream_id, const uint8_t* data, size_t len, void* user_data)
{
+ (void)session;
+ (void)flags;
DOHConnection* conn = reinterpret_cast<DOHConnection*>(user_data);
auto& query = conn->d_queries[stream_id];
query.insert(query.end(), data, data + len);
static int on_stream_close_callback(nghttp2_session* session, int32_t stream_id, uint32_t error_code, void* user_data)
{
+ (void)session;
+ (void)stream_id;
+ (void)user_data;
if (error_code == 0) {
return 0;
}
IOState tryConnect(bool fastOpen, const ComboAddress& remote) override
{
+ (void)fastOpen;
+ (void)remote;
auto step = getStep();
BOOST_REQUIRE_EQUAL(step.request, ExpectedStep::ExpectedRequest::connectToBackend);
void setSession(std::unique_ptr<TLSSession>& session) override
{
+ (void)session;
}
std::vector<int> getAsyncFDs() override
void connect(bool fastOpen, const ComboAddress& remote, const struct timeval& timeout) override
{
+ (void)fastOpen;
+ (void)remote;
+ (void)timeout;
}
size_t read(void* buffer, size_t bufferSize, const struct timeval& readTimeout, const struct timeval& totalTimeout = {0, 0}, bool allowIncomplete = false) override
{
+ (void)buffer;
+ (void)bufferSize;
+ (void)readTimeout;
+ (void)totalTimeout;
+ (void)allowIncomplete;
return 0;
}
size_t write(const void* buffer, size_t bufferSize, const struct timeval& writeTimeout) override
{
+ (void)buffer;
+ (void)bufferSize;
+ (void)writeTimeout;
return 0;
}
{ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, std::numeric_limits<size_t>::max()},
/* acknowledge settings */
{ExpectedStep::ExpectedRequest::writeToBackend, IOState::Done, std::numeric_limits<size_t>::max(), [&firstQueryDone](int desc) {
+ (void)desc;
firstQueryDone = true;
}},
/* headers */
{ExpectedStep::ExpectedRequest::writeToBackend, IOState::Done, std::numeric_limits<size_t>::max(), [](int desc) {
+ (void)desc;
}},
/* data */
{ExpectedStep::ExpectedRequest::writeToBackend, IOState::Done, std::numeric_limits<size_t>::max(), [](int desc) {
{ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, std::numeric_limits<size_t>::max()},
/* later the backend sends a go away frame */
{ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, std::numeric_limits<size_t>::max(), [](int desc) {
+ (void)desc;
s_connectionBuffers.at(desc)->submitGoAway();
}},
{ExpectedStep::ExpectedRequest::closeBackend, IOState::Done},
auto sender = std::make_shared<MockupQuerySender>();
sender->d_id = counter;
sender->d_customHandler = [](uint16_t id, const struct timeval&, TCPResponse&& resp) {
+ (void)id;
BOOST_CHECK_EQUAL(resp.d_buffer.size(), 11U);
/* simulate an exception, since DoH and UDP frontends will process the query right away,
while TCP and DoT will first pass it back to the TCP worker thread */
{ExpectedStep::ExpectedRequest::writeToBackend, IOState::Done, std::numeric_limits<size_t>::max()},
/* data */
{ExpectedStep::ExpectedRequest::writeToBackend, IOState::NeedWrite, std::numeric_limits<size_t>::max(), [&timeout](int desc) {
+ (void)desc;
timeout = true;
}},
{ExpectedStep::ExpectedRequest::closeBackend, IOState::Done},
{ExpectedStep::ExpectedRequest::writeToBackend, IOState::Done, std::numeric_limits<size_t>::max()},
/* data */
{ExpectedStep::ExpectedRequest::writeToBackend, IOState::Done, std::numeric_limits<size_t>::max(), [&timeout](int desc) {
+ (void)desc;
/* set the timeout flag now, since the timeout occurs while waiting for the descriptor to become readable */
timeout = true;
}},
{ExpectedStep::ExpectedRequest::writeToBackend, IOState::Done, std::numeric_limits<size_t>::max()},
/* read ends up as a time out since nghttp2 filters the frame with the wrong stream ID */
{ExpectedStep::ExpectedRequest::readFromBackend, IOState::NeedRead, 0, [&timeout](int desc) {
+ (void)desc;
/* set the timeout flag now, since the timeout occurs while waiting for the descriptor to become readable */
timeout = true;
}},
std::unique_ptr<TLSConnection> getConnection(int socket, const struct timeval& timeout, time_t now) override
{
+ (void)timeout;
+ (void)now;
return std::make_unique<MockupTLSConnection>(socket);
}
std::unique_ptr<TLSConnection> getClientConnection(const std::string& host, bool hostIsAddr, int socket, const struct timeval& timeout) override
{
+ (void)host;
+ (void)hostIsAddr;
+ (void)timeout;
return std::make_unique<MockupTLSConnection>(socket, true, d_needProxyProtocol);
}
void rotateTicketsKey(time_t now) override
{
+ (void)now;
}
size_t getTicketsKeysCount() override
int run(struct timeval* tv, int timeout = 500) override
{
+ (void)timeout;
int ret = 0;
gettimeofday(tv, nullptr); // MANDATORY
void getAvailableFDs(std::vector<int>& fds, int timeout) override
{
+ (void)fds;
+ (void)timeout;
}
void addFD(int fd, FDMultiplexer::EventKind kind) override
{
+ (void)fd;
+ (void)kind;
}
void removeFD(int fd, FDMultiplexer::EventKind) override
{
+ (void)fd;
}
string getName() const override
bool checkDNSCryptQuery(const ClientState& cs, PacketBuffer& query, std::unique_ptr<DNSCryptQuery>& dnsCryptQuery, time_t now, bool tcp)
{
+ (void)cs;
+ (void)query;
+ (void)dnsCryptQuery;
+ (void)now;
+ (void)tcp;
return false;
}
bool checkQueryHeaders(const struct dnsheader& dnsHeader, ClientState& clientState)
{
+ (void)dnsHeader;
+ (void)clientState;
return true;
}
uint64_t uptimeOfProcess(const std::string& str)
{
+ (void)str;
return 0;
}
void handleResponseSent(const InternalQueryState& ids, double udiff, const ComboAddress& client, const ComboAddress& backend, unsigned int size, const dnsheader& cleartextDH, dnsdist::Protocol protocol, bool fromBackend)
{
+ (void)ids;
+ (void)udiff;
+ (void)client;
+ (void)backend;
+ (void)size;
+ (void)cleartextDH;
+ (void)protocol;
+ (void)fromBackend;
}
void handleResponseSent(const DNSName& qname, const QType& qtype, double udiff, const ComboAddress& client, const ComboAddress& backend, unsigned int size, const dnsheader& cleartextDH, dnsdist::Protocol outgoingProtocol, dnsdist::Protocol incomingProtocol, bool fromBackend)
bool responseContentMatches(const PacketBuffer& response, const DNSName& qname, const uint16_t qtype, const uint16_t qclass, const std::shared_ptr<DownstreamState>& remote, bool allowEmptyResponse)
{
+ (void)response;
+ (void)qname;
+ (void)qtype;
+ (void)qclass;
+ (void)remote;
+ (void)allowEmptyResponse;
return true;
}
IOState tryRead(PacketBuffer& buffer, size_t& pos, size_t toRead, bool allowIncomplete=false) override
{
+ (void)allowIncomplete;
auto step = getStep();
BOOST_REQUIRE_EQUAL(step.request, !d_client ? ExpectedStep::ExpectedRequest::readFromClient : ExpectedStep::ExpectedRequest::readFromBackend);
IOState tryConnect(bool fastOpen, const ComboAddress& remote) override
{
+ (void)fastOpen;
+ (void)remote;
auto step = getStep();
BOOST_REQUIRE_EQUAL(step.request, ExpectedStep::ExpectedRequest::connectToBackend);
void setSession(std::unique_ptr<TLSSession>& session) override
{
+ (void)session;
}
/* unused in that context, don't bother */
void connect(bool fastOpen, const ComboAddress& remote, const struct timeval& timeout) override
{
+ (void)fastOpen;
+ (void)remote;
+ (void)timeout;
}
size_t read(void* buffer, size_t bufferSize, const struct timeval&readTimeout, const struct timeval& totalTimeout={0,0}, bool allowIncomplete=false) override
{
+ (void)buffer;
+ (void)bufferSize;
+ (void)readTimeout;
+ (void)totalTimeout;
+ (void)allowIncomplete;
return 0;
}
size_t write(const void* buffer, size_t bufferSize, const struct timeval& writeTimeout) override
{
+ (void)buffer;
+ (void)bufferSize;
+ (void)writeTimeout;
return 0;
}
private:
std::unique_ptr<TLSConnection> getConnection(int socket, const struct timeval& timeout, time_t now) override
{
+ (void)timeout;
+ (void)now;
return std::make_unique<MockupTLSConnection>(socket);
}
std::unique_ptr<TLSConnection> getClientConnection(const std::string& host, bool hostIsAddr, int socket, const struct timeval& timeout) override
{
+ (void)host;
+ (void)hostIsAddr;
+ (void)timeout;
return std::make_unique<MockupTLSConnection>(socket, true);
}
void rotateTicketsKey(time_t now) override
{
+ (void)now;
}
size_t getTicketsKeysCount() override
int run(struct timeval* tv, int timeout=500) override
{
+ (void)timeout;
int ret = 0;
gettimeofday(tv, nullptr); // MANDATORY
void getAvailableFDs(std::vector<int>& fds, int timeout) override
{
+ (void)fds;
+ (void)timeout;
}
void addFD(int fd, FDMultiplexer::EventKind kind) override
{
+ (void)fd;
+ (void)kind;
}
void removeFD(int fd, FDMultiplexer::EventKind) override
{
+ (void)fd;
}
string getName() const override
{ ExpectedStep::ExpectedRequest::closeClient, IOState::Done },
};
s_processQuery = [](DNSQuestion& dq, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
+ (void)dq;
+ (void)selectedBackend;
return ProcessQueryResult::Drop;
};
{ ExpectedStep::ExpectedRequest::closeClient, IOState::Done },
};
s_processQuery = [](DNSQuestion& dq, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
+ (void)dq;
+ (void)selectedBackend;
// Would be nicer to actually turn it into a response
return ProcessQueryResult::SendAnswer;
};
{ ExpectedStep::ExpectedRequest::closeClient, IOState::Done },
};
s_processQuery = [](DNSQuestion& dq, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
+ (void)dq;
+ (void)selectedBackend;
// Would be nicer to actually turn it into a response
return ProcessQueryResult::SendAnswer;
};
{ ExpectedStep::ExpectedRequest::closeClient, IOState::Done },
};
s_processQuery = [](DNSQuestion& dq, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
+ (void)dq;
+ (void)selectedBackend;
throw std::runtime_error("Something unexpected happened");
};
s_steps.push_back({ ExpectedStep::ExpectedRequest::closeClient, IOState::Done });
s_processQuery = [](DNSQuestion& dq, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
+ (void)dq;
+ (void)selectedBackend;
// Would be nicer to actually turn it into a response
return ProcessQueryResult::SendAnswer;
};
{ ExpectedStep::ExpectedRequest::closeClient, IOState::Done },
};
s_processQuery = [](DNSQuestion& dq, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
+ (void)dq;
+ (void)selectedBackend;
/* should not be reached */
BOOST_CHECK(false);
return ProcessQueryResult::SendAnswer;
{ ExpectedStep::ExpectedRequest::closeClient, IOState::Done },
};
s_processQuery = [](DNSQuestion& dq, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
+ (void)dq;
+ (void)selectedBackend;
return ProcessQueryResult::SendAnswer;
};
{ ExpectedStep::ExpectedRequest::closeClient, IOState::Done },
};
s_processQuery = [](DNSQuestion& dq, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
+ (void)dq;
+ (void)selectedBackend;
return ProcessQueryResult::SendAnswer;
};
{ ExpectedStep::ExpectedRequest::closeClient, IOState::Done },
};
s_processQuery = [](DNSQuestion& dq, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
+ (void)dq;
+ (void)selectedBackend;
return ProcessQueryResult::SendAnswer;
};
{ ExpectedStep::ExpectedRequest::closeClient, IOState::Done },
};
s_processQuery = [](DNSQuestion& dq, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
+ (void)dq;
+ (void)selectedBackend;
return ProcessQueryResult::SendAnswer;
};
{ ExpectedStep::ExpectedRequest::closeClient, IOState::Done },
};
s_processQuery = [](DNSQuestion& dq, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
+ (void)dq;
+ (void)selectedBackend;
return ProcessQueryResult::SendAnswer;
};
{ ExpectedStep::ExpectedRequest::closeBackend, IOState::Done },
};
s_processQuery = [backend](DNSQuestion& dq, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
+ (void)dq;
selectedBackend = backend;
return ProcessQueryResult::PassToBackend;
};
s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
+ (void)response;
+ (void)dr;
+ (void)muted;
return true;
};
{ ExpectedStep::ExpectedRequest::closeBackend, IOState::Done },
};
s_processQuery = [backend](DNSQuestion& dq, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
+ (void)dq;
selectedBackend = backend;
return ProcessQueryResult::PassToBackend;
};
s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
+ (void)response;
+ (void)dr;
+ (void)muted;
throw std::runtime_error("Unexpected error while processing the response");
};
{ ExpectedStep::ExpectedRequest::closeBackend, IOState::Done },
};
s_processQuery = [backend](DNSQuestion& dq, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
+ (void)dq;
selectedBackend = backend;
return ProcessQueryResult::PassToBackend;
};
s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
+ (void)response;
+ (void)dr;
+ (void)muted;
return false;
};
{ ExpectedStep::ExpectedRequest::closeBackend, IOState::Done },
};
s_processQuery = [backend](DNSQuestion& dq, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
+ (void)dq;
selectedBackend = backend;
return ProcessQueryResult::PassToBackend;
};
s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
+ (void)response;
+ (void)dr;
+ (void)muted;
return true;
};
{ ExpectedStep::ExpectedRequest::closeClient, IOState::Done },
};
s_processQuery = [](DNSQuestion& dq, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
+ (void)dq;
+ (void)selectedBackend;
return ProcessQueryResult::SendAnswer;
};
s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
+ (void)response;
+ (void)dr;
+ (void)muted;
return true;
};
{ ExpectedStep::ExpectedRequest::closeBackend, IOState::Done },
};
s_processQuery = [backend](DNSQuestion& dq, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
+ (void)dq;
selectedBackend = backend;
return ProcessQueryResult::PassToBackend;
};
s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
+ (void)response;
+ (void)dr;
+ (void)muted;
return true;
};
};
s_processQuery = [backend](DNSQuestion& dq, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
+ (void)dq;
selectedBackend = backend;
return ProcessQueryResult::PassToBackend;
};
s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
+ (void)response;
+ (void)dr;
+ (void)muted;
return true;
};
{ ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, query.size() - 2 },
/* opening a connection to the backend (5 tries by default) */
{ ExpectedStep::ExpectedRequest::connectToBackend, IOState::Done, 0, [](int descriptor) {
+ (void)descriptor;
throw NetworkError("Connection refused by the backend");
}
},
{ ExpectedStep::ExpectedRequest::closeBackend, IOState::Done },
{ ExpectedStep::ExpectedRequest::connectToBackend, IOState::Done, 0, [](int descriptor) {
+ (void)descriptor;
throw NetworkError("Connection refused by the backend");
}
},
{ ExpectedStep::ExpectedRequest::closeBackend, IOState::Done },
{ ExpectedStep::ExpectedRequest::connectToBackend, IOState::Done, 0, [](int descriptor) {
+ (void)descriptor;
throw NetworkError("Connection refused by the backend");
}
},
{ ExpectedStep::ExpectedRequest::closeBackend, IOState::Done },
{ ExpectedStep::ExpectedRequest::connectToBackend, IOState::Done, 0, [](int descriptor) {
+ (void)descriptor;
throw NetworkError("Connection refused by the backend");
}
},
{ ExpectedStep::ExpectedRequest::closeBackend, IOState::Done },
{ ExpectedStep::ExpectedRequest::connectToBackend, IOState::Done, 0, [](int descriptor) {
+ (void)descriptor;
throw NetworkError("Connection refused by the backend");
}
},
};
s_processQuery = [backend](DNSQuestion& dq, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
-
+ (void)dq;
selectedBackend = backend;
return ProcessQueryResult::PassToBackend;
};
s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
+ (void)response;
+ (void)dr;
+ (void)muted;
return true;
};
};
s_processQuery = [backend](DNSQuestion& dq, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
-
+ (void)dq;
selectedBackend = backend;
return ProcessQueryResult::PassToBackend;
};
s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
+ (void)response;
+ (void)dr;
+ (void)muted;
return true;
};
};
s_processQuery = [backend](DNSQuestion& dq, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
+ (void)dq;
selectedBackend = backend;
return ProcessQueryResult::PassToBackend;
};
s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
+ (void)response;
+ (void)dr;
+ (void)muted;
return true;
};
};
s_processQuery = [backend](DNSQuestion& dq, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
+ (void)dq;
selectedBackend = backend;
return ProcessQueryResult::PassToBackend;
};
s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
+ (void)response;
+ (void)dr;
+ (void)muted;
return true;
};
};
s_processQuery = [backend](DNSQuestion& dq, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
+ (void)dq;
selectedBackend = backend;
return ProcessQueryResult::PassToBackend;
};
s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
+ (void)response;
+ (void)dr;
+ (void)muted;
return true;
};
{ ExpectedStep::ExpectedRequest::closeBackend, IOState::Done },
/* and now reconnection fails (1) */
{ ExpectedStep::ExpectedRequest::connectToBackend, IOState::Done, 0, [](int descriptor) {
+ (void)descriptor;
throw NetworkError("Connection refused by the backend");
}
},
{ ExpectedStep::ExpectedRequest::closeBackend, IOState::Done },
/* 2 */
{ ExpectedStep::ExpectedRequest::connectToBackend, IOState::Done, 0, [](int descriptor) {
+ (void)descriptor;
throw NetworkError("Connection refused by the backend");
}
},
{ ExpectedStep::ExpectedRequest::closeBackend, IOState::Done },
/* 3 */
{ ExpectedStep::ExpectedRequest::connectToBackend, IOState::Done, 0, [](int descriptor) {
+ (void)descriptor;
throw NetworkError("Connection refused by the backend");
}
},
{ ExpectedStep::ExpectedRequest::closeBackend, IOState::Done },
/* 4 */
{ ExpectedStep::ExpectedRequest::connectToBackend, IOState::Done, 0, [](int descriptor) {
+ (void)descriptor;
throw NetworkError("Connection refused by the backend");
}
},
};
s_processQuery = [backend](DNSQuestion& dq, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
+ (void)dq;
selectedBackend = backend;
return ProcessQueryResult::PassToBackend;
};
s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
+ (void)response;
+ (void)dr;
+ (void)muted;
return true;
};
};
s_processQuery = [backend](DNSQuestion& dq, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
+ (void)dq;
selectedBackend = backend;
return ProcessQueryResult::PassToBackend;
};
s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
+ (void)response;
+ (void)dr;
+ (void)muted;
return true;
};
};
s_processQuery = [backend](DNSQuestion& dq, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
+ (void)dq;
selectedBackend = backend;
return ProcessQueryResult::PassToBackend;
};
s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
+ (void)response;
+ (void)dr;
+ (void)muted;
return true;
};
};
s_processQuery = [backend](DNSQuestion& dq, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
+ (void)dq;
selectedBackend = backend;
return ProcessQueryResult::PassToBackend;
};
s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
+ (void)response;
+ (void)dr;
+ (void)muted;
return true;
};
s_steps.push_back({ ExpectedStep::ExpectedRequest::closeClient, IOState::Done });
s_processQuery = [backend](DNSQuestion& dq, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
+ (void)dq;
selectedBackend = backend;
return ProcessQueryResult::PassToBackend;
};
s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
+ (void)response;
+ (void)dr;
+ (void)muted;
return true;
};
};
s_processQuery = [backend](DNSQuestion& dq, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
+ (void)dq;
selectedBackend = backend;
dq.asynchronous = true;
/* note that we do nothing with the query, we just tell the frontend it was dealt with */
return ProcessQueryResult::Asynchronous;
};
s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
+ (void)response;
+ (void)dr;
+ (void)muted;
return true;
};
};
s_processQuery = [backend](DNSQuestion& dq, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
+ (void)dq;
selectedBackend = backend;
return ProcessQueryResult::PassToBackend;
};
s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
+ (void)response;
+ (void)dr;
+ (void)muted;
return true;
};
return ProcessQueryResult::PassToBackend;
};
s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
+ (void)response;
+ (void)dr;
+ (void)muted;
return true;
};
/* reading a query from the client (5) */
{ ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 2 },
{ ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, queries.at(4).size() - 2, [&threadData,&backendDesc](int desc) {
+ (void)desc;
/* set the backend descriptor as ready now */
dynamic_cast<MockupFDMultiplexer*>(threadData.mplexer.get())->setReady(backendDesc);
} },
/* reading a response from the backend (5) */
{ ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, 2 },
{ ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, responses.at(4).size() - 2, [&threadData](int desc) {
+ (void)desc;
/* set the client descriptor as ready to resume sending */
dynamic_cast<MockupFDMultiplexer*>(threadData.mplexer.get())->setReady(-1);
} },
};
s_processQuery = [backend](DNSQuestion& dq, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
+ (void)dq;
selectedBackend = backend;
return ProcessQueryResult::PassToBackend;
};
s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
+ (void)response;
+ (void)dr;
+ (void)muted;
return true;
};
{ ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, queries.at(1).size() - 2 },
/* query is dropped, closing the connection to the client */
{ ExpectedStep::ExpectedRequest::closeClient, IOState::Done, 0, [&timeout](int desc) {
+ (void)desc;
timeout = true;
} },
/* closing a connection to the backend after a timeout */
counter = 0;
s_processQuery = [backend,&counter](DNSQuestion& dq, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
+ (void)dq;
if (counter == 0) {
++counter;
selectedBackend = backend;
return ProcessQueryResult::Drop;
};
s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
+ (void)response;
+ (void)dr;
+ (void)muted;
return true;
};
{ ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, queries.at(1).size() - 2 },
/* query is dropped, closing the connection to the client */
{ ExpectedStep::ExpectedRequest::closeClient, IOState::Done, 0, [&threadData,&backendDescriptor](int desc) {
+ (void)desc;
/* the backend descriptor becomes ready */
dynamic_cast<MockupFDMultiplexer*>(threadData.mplexer.get())->setReady(backendDescriptor);
} },
counter = 0;
s_processQuery = [backend,&counter](DNSQuestion& dq, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
+ (void)dq;
if (counter == 0) {
++counter;
selectedBackend = backend;
return ProcessQueryResult::Drop;
};
s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
+ (void)response;
+ (void)dr;
+ (void)muted;
return true;
};
{ ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, responses.at(4).size() - 2 },
/* sending response (3) to the client */
{ ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, responses.at(4).size(), [&timeout](int desc) {
+ (void)desc;
timeout = true;
} },
/* closing a connection to the backend */
};
s_processQuery = [backend](DNSQuestion& dq, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
+ (void)dq;
selectedBackend = backend;
return ProcessQueryResult::PassToBackend;
};
s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
+ (void)response;
+ (void)dr;
+ (void)muted;
return true;
};
{ ExpectedStep::ExpectedRequest::closeBackend, IOState::Done },
/* try opening a new connection to the backend, it fails (5) times */
{ ExpectedStep::ExpectedRequest::connectToBackend, IOState::Done, 0, [](int desc) {
+ (void)desc;
throw NetworkError("Connection refused by the backend");
} },
{ ExpectedStep::ExpectedRequest::closeBackend, IOState::Done },
/* try opening a new connection to the backend, it fails (5) times */
{ ExpectedStep::ExpectedRequest::connectToBackend, IOState::Done,0, [](int desc) {
+ (void)desc;
throw NetworkError("Connection refused by the backend");
} },
{ ExpectedStep::ExpectedRequest::closeBackend, IOState::Done },
/* try opening a new connection to the backend, it fails (5) times */
{ ExpectedStep::ExpectedRequest::connectToBackend, IOState::Done,0, [](int desc) {
+ (void)desc;
throw NetworkError("Connection refused by the backend");
} },
{ ExpectedStep::ExpectedRequest::closeBackend, IOState::Done },
/* try opening a new connection to the backend, it fails (5) times */
{ ExpectedStep::ExpectedRequest::connectToBackend, IOState::Done,0, [](int desc) {
+ (void)desc;
throw NetworkError("Connection refused by the backend");
} },
{ ExpectedStep::ExpectedRequest::closeBackend, IOState::Done },
/* try opening a new connection to the backend, it fails (5) times */
{ ExpectedStep::ExpectedRequest::connectToBackend, IOState::Done,0, [](int desc) {
+ (void)desc;
throw NetworkError("Connection refused by the backend");
} },
/* closing a connection to the backend, client becomes ready */
{ ExpectedStep::ExpectedRequest::closeBackend, IOState::Done, 0, [&threadData](int desc) {
+ (void)desc;
/* the client descriptor is ready */
dynamic_cast<MockupFDMultiplexer*>(threadData.mplexer.get())->setReady(-1);
} },
};
s_processQuery = [backend](DNSQuestion& dq, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
+ (void)dq;
selectedBackend = backend;
return ProcessQueryResult::PassToBackend;
};
s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
+ (void)response;
+ (void)dr;
+ (void)muted;
return true;
};
} },
/* no more query from the client for now */
{ ExpectedStep::ExpectedRequest::readFromClient, IOState::NeedRead, 0 , [&threadData](int desc) {
+ (void)desc;
/* the client descriptor becomes NOT ready */
dynamic_cast<MockupFDMultiplexer*>(threadData.mplexer.get())->setNotReady(-1);
} },
{ ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, axfrResponses.at(2).size() - 2 },
/* sending response (3) to the client */
{ ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, axfrResponses.at(2).size(), [&threadData](int desc) {
+ (void)desc;
/* the client descriptor becomes ready */
dynamic_cast<MockupFDMultiplexer*>(threadData.mplexer.get())->setReady(-1);
} },
};
s_processQuery = [backend](DNSQuestion& dq, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
+ (void)dq;
selectedBackend = backend;
return ProcessQueryResult::PassToBackend;
};
s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
+ (void)response;
+ (void)dr;
+ (void)muted;
return true;
};
} },
/* no more query from the client for now */
{ ExpectedStep::ExpectedRequest::readFromClient, IOState::NeedRead, 0 , [&threadData](int desc) {
+ (void)desc;
/* the client descriptor becomes NOT ready */
dynamic_cast<MockupFDMultiplexer*>(threadData.mplexer.get())->setNotReady(-1);
} },
};
s_processQuery = [proxyEnabledBackend](DNSQuestion& dq, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
+ (void)dq;
selectedBackend = proxyEnabledBackend;
return ProcessQueryResult::PassToBackend;
};
s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
+ (void)response;
+ (void)dr;
+ (void)muted;
return true;
};
{ ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, firstResponse.size() - 2 },
/* sending response (1) to the client */
{ ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, firstResponse.size(), [&threadData](int desc) {
+ (void)desc;
/* client descriptor becomes ready */
dynamic_cast<MockupFDMultiplexer*>(threadData.mplexer.get())->setReady(-1);
} },
{ ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, ixfrResponses.at(0).size() - 2 },
/* sending response (ixfr 1) to the client */
{ ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, ixfrResponses.at(0).size(), [&threadData](int desc) {
+ (void)desc;
/* the client descriptor becomes ready */
dynamic_cast<MockupFDMultiplexer*>(threadData.mplexer.get())->setReady(-1);
} },
};
s_processQuery = [backend](DNSQuestion& dq, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
+ (void)dq;
selectedBackend = backend;
return ProcessQueryResult::PassToBackend;
};
s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
+ (void)response;
+ (void)dr;
+ (void)muted;
return true;
};
};
s_processQuery = [proxyEnabledBackend](DNSQuestion& dq, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
+ (void)dq;
selectedBackend = proxyEnabledBackend;
return ProcessQueryResult::PassToBackend;
};
s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
+ (void)response;
+ (void)dr;
+ (void)muted;
return true;
};
};
s_processQuery = [proxyEnabledBackend](DNSQuestion& dq, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
+ (void)dq;
selectedBackend = proxyEnabledBackend;
return ProcessQueryResult::PassToBackend;
};
s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
+ (void)response;
+ (void)dr;
+ (void)muted;
return true;
};
/* reading a third query from the client */
{ ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 2 },
{ ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, queries.at(2).size() - 2, [&timeout](int desc) {
+ (void)desc;
timeout = true;
} },
/* trying to read more from the client but nothing to read */
};
s_processQuery = [backend](DNSQuestion& dq, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
+ (void)dq;
selectedBackend = backend;
return ProcessQueryResult::PassToBackend;
};
s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
+ (void)response;
+ (void)dr;
+ (void)muted;
return true;
};
{ ExpectedStep::ExpectedRequest::readFromBackend, IOState::NeedRead, 0 },
/* nothing more to read from the client at that moment */
{ ExpectedStep::ExpectedRequest::readFromClient, IOState::NeedRead, 0, [&threadData, &backend1Desc](int desc) {
+ (void)desc;
/* but the first backend becomes readable */
dynamic_cast<MockupFDMultiplexer*>(threadData.mplexer.get())->setReady(backend1Desc);
} },
{ ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, responses.at(2).size() - 2 },
/* sending it to the client */
{ ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, responses.at(2).size(), [&threadData,&backend1Desc,&backend2Desc](int desc) {
+ (void)desc;
/* backend 2 is no longer readable, backend 1 becomes readable */
dynamic_cast<MockupFDMultiplexer*>(threadData.mplexer.get())->setNotReady(backend2Desc);
dynamic_cast<MockupFDMultiplexer*>(threadData.mplexer.get())->setReady(backend1Desc);
{ ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, responses.at(4).size() - 2 },
/* sending it to the client */
{ ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, responses.at(4).size(), [&threadData,&backend1Desc,&backend2Desc](int desc) {
+ (void)desc;
/* backend 1 is no longer readable, backend 2 becomes readable */
dynamic_cast<MockupFDMultiplexer*>(threadData.mplexer.get())->setNotReady(backend1Desc);
dynamic_cast<MockupFDMultiplexer*>(threadData.mplexer.get())->setReady(backend2Desc);
{ ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, responses.at(3).size() - 2 },
/* sending it to the client */
{ ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, responses.at(3).size(), [&threadData,&backend2Desc](int desc) {
+ (void)desc;
/* backend 2 is no longer readable */
dynamic_cast<MockupFDMultiplexer*>(threadData.mplexer.get())->setNotReady(backend2Desc);
/* client becomes readable */
};
s_processQuery = [backend1](DNSQuestion& dq, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
+ (void)dq;
selectedBackend = backend1;
return ProcessQueryResult::PassToBackend;
};
s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
+ (void)response;
+ (void)dr;
+ (void)muted;
return true;
};
} },
/* sending it to the client. we don't have anything else to send to the client, no new query from it either, until we time out */
{ ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, responses.at(0).size(), [&timeout](int desc) {
+ (void)desc;
timeout = true;
} },
/* closing a connection to the backend */
};
s_processQuery = [backend](DNSQuestion& dq, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
+ (void)dq;
selectedBackend = backend;
return ProcessQueryResult::PassToBackend;
};
s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
+ (void)response;
+ (void)dr;
+ (void)muted;
return true;
};
{ ExpectedStep::ExpectedRequest::writeToBackend, IOState::Done, queries.at(4).size() },
/* no response ready yet, client stops being readable, first backend has a response */
{ ExpectedStep::ExpectedRequest::readFromBackend, IOState::NeedRead, 0, [&threadData,&backendDescriptors](int desc) {
+ (void)desc;
dynamic_cast<MockupFDMultiplexer*>(threadData.mplexer.get())->setReady(backendDescriptors.at(0));
} },
/* trying to read from the client but nothing yet */
{ ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, responses.at(0).size() - 2 },
/* sending it to the client */
{ ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, responses.at(0).size(), [&threadData,&backendDescriptors](int desc) {
+ (void)desc;
dynamic_cast<MockupFDMultiplexer*>(threadData.mplexer.get())->setReady(backendDescriptors.at(2));
} },
/* reading response (3) from the third backend (3) */
{ ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, responses.at(2).size() - 2 },
/* sending it to the client */
{ ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, responses.at(2).size(), [&threadData,&backendDescriptors](int desc) {
+ (void)desc;
dynamic_cast<MockupFDMultiplexer*>(threadData.mplexer.get())->setReady(backendDescriptors.at(1));
} },
/* reading response (2) from the second backend (2) */
{ ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, responses.at(1).size() - 2 },
/* sending it to the client */
{ ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, responses.at(1).size(), [&threadData,&backendDescriptors](int desc) {
+ (void)desc;
dynamic_cast<MockupFDMultiplexer*>(threadData.mplexer.get())->setReady(backendDescriptors.at(4));
} },
/* reading response (5) from the fifth backend (5) */
{ ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, responses.at(4).size() - 2 },
/* sending it to the client */
{ ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, responses.at(4).size(), [&threadData,&backendDescriptors](int desc) {
+ (void)desc;
dynamic_cast<MockupFDMultiplexer*>(threadData.mplexer.get())->setReady(backendDescriptors.at(3));
} },
/* reading response (4) from the fourth backend (4) */
{ ExpectedStep::ExpectedRequest::readFromBackend, IOState::Done, responses.at(3).size() - 2 },
/* sending it to the client */
{ ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, responses.at(3).size(), [&threadData](int desc) {
+ (void)desc;
dynamic_cast<MockupFDMultiplexer*>(threadData.mplexer.get())->setReady(-1);
} },
/* client closes the connection */
};
s_processQuery = [backend](DNSQuestion& dq, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
+ (void)dq;
selectedBackend = backend;
return ProcessQueryResult::PassToBackend;
};
s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
+ (void)response;
+ (void)dr;
+ (void)muted;
return true;
};
{ ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 2 },
{ ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, queries.at(1).size() - 2 },
{ ExpectedStep::ExpectedRequest::readFromClient, IOState::NeedRead, 0, [&timeout](int desc) {
+ (void)desc;
timeout = true;
}},
/* close the connection with the client */
return ProcessQueryResult::Asynchronous;
};
s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
+ (void)response;
+ (void)dr;
+ (void)muted;
return true;
};