From: Otto Moerbeek Date: Mon, 20 Oct 2025 15:02:33 +0000 (+0200) Subject: Matching logic X-Git-Tag: rec-5.4.0-alpha1~103^2~15 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a4dac655a60ed9eaaa61bc230429f4fb3e058c41;p=thirdparty%2Fpdns.git Matching logic Signed-off-by: Otto Moerbeek --- diff --git a/pdns/protozero-trace.cc b/pdns/protozero-trace.cc index e86f6da5e0..66a524ff85 100644 --- a/pdns/protozero-trace.cc +++ b/pdns/protozero-trace.cc @@ -553,18 +553,13 @@ KeyValue KeyValue::decode(protozero::pbf_reader& reader) return value; } -void extractOTraceIDs(const EDNSOptionViewMap& map, pdns::trace::InitialSpanInfo& span) +bool extractOTraceIDs(const EDNSOptionViewMap& map, pdns::trace::InitialSpanInfo& span) { - // traceid gets set from edns options (if available and well-formed), otherwise random + // traceid gets set from edns options (if available and well-formed) // parent_span_id gets set from edns options (if available and well-formed, otherwise it remains cleared (no parent)) - // span_id gets inited randomly auto traceidset = extractOTraceIDs(map, EDNSOptionCode::OTTRACEIDS, span.trace_id, span.parent_span_id); - if (!traceidset) { - span.trace_id.makeRandom(); - } - // Empty parent span id indicated the client did not set one, thats fine - span.span_id.makeRandom(); + return traceidset; } /** diff --git a/pdns/protozero-trace.hh b/pdns/protozero-trace.hh index 23039fa7bb..3735d01826 100644 --- a/pdns/protozero-trace.hh +++ b/pdns/protozero-trace.hh @@ -818,7 +818,7 @@ private: const size_t size; }; -void extractOTraceIDs(const EDNSOptionViewMap& map, pdns::trace::InitialSpanInfo& span); +bool extractOTraceIDs(const EDNSOptionViewMap& map, pdns::trace::InitialSpanInfo& span); bool extractOTraceIDs(const EDNSOptionViewMap& map, const EDNSOptionCode::EDNSOptionCodeEnum& eoc, pdns::trace::TraceID& traceID, pdns::trace::SpanID& spanID); } // namespace pdns::trace diff --git a/pdns/recursordist/pdns_recursor.cc b/pdns/recursordist/pdns_recursor.cc index 69109303fc..790cdd8703 100644 --- a/pdns/recursordist/pdns_recursor.cc +++ b/pdns/recursordist/pdns_recursor.cc @@ -1870,7 +1870,7 @@ void startDoResolve(void* arg) // NOLINT(readability-function-cognitive-complexi string otData = otTrace.encode(); pbMessage.setOpenTelemetryData(otData); } - // Currently only set if an OT trace is generated + // It can be set even if no OT Trace data was generated if (resolver.d_otTrace.trace_id != pdns::trace::s_emptyTraceID) { pbMessage.setOpenTelemetryTraceID(resolver.d_otTrace.trace_id); } @@ -2144,6 +2144,40 @@ bool expectProxyProtocol(const ComboAddress& from, const ComboAddress& listenAdd return false; } +static bool match(const std::unique_ptr& conditions, const ComboAddress& source, const DNSName& qname, QType qtype, uint16_t qid, bool edns_option_present) +{ + if (conditions == nullptr || conditions->size() == 0) { + cerr << "match 0 false" << endl; + return false; + } + if (auto const* match = conditions->lookup(source); match != nullptr) { + cerr << "match 1" << endl; + const auto& condition = match->second; + if (condition.d_traceid_only) { + cerr << "match 2 false" << endl; + return false; + } + if (condition.d_edns_option_required && !edns_option_present) { + cerr << "match 3 false" << endl; + return false; + } + if (condition.d_qid && condition.d_qid != qid) { + cerr << "match 4 false" << endl; + return false; + } + if (condition.d_qtypes && condition.d_qtypes->count(qtype) == 0) { + cerr << "match 5 false" << endl; + return false; + } + if (condition.d_qnames && !condition.d_qnames->check(qname)) { + cerr << "match 6 false" << endl; + return false; + } + } + cerr << "match return true" << endl; + return true; +} + // fromaddr: the address the query is coming from // destaddr: the address the query was received on // source: the address we assume the query is coming from, might be set by proxy protocol @@ -2249,7 +2283,10 @@ static string* doProcessUDPQuestion(const std::string& question, const ComboAddr ecsParsed = true; if (SyncRes::eventTraceEnabled(SyncRes::event_trace_to_ot)) { - pdns::trace::extractOTraceIDs(ednsOptions, otTrace); + bool ednsFound = pdns::trace::extractOTraceIDs(ednsOptions, otTrace); + if (!match(t_OTConditions, source, qname, qtype, ntohs(headerdata->id), ednsFound)) { + eventTrace.setEnabled(false); + } } if (t_pdl) { diff --git a/pdns/recursordist/rec-lua-conf.hh b/pdns/recursordist/rec-lua-conf.hh index d80f446895..b9b077cbf3 100644 --- a/pdns/recursordist/rec-lua-conf.hh +++ b/pdns/recursordist/rec-lua-conf.hh @@ -100,8 +100,8 @@ using ProxyMapping = NetmaskTree; struct OpenTelemetryTraceCondition { - SuffixMatchTree d_qnames; - std::unordered_set d_qtypes; + std::optional d_qnames; + std::optional> d_qtypes; std::optional d_qid; bool d_edns_option_required{false}; bool d_traceid_only{false}; diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index 75f9452c75..349e5eac45 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -108,6 +108,7 @@ uint32_t g_disthashseed; bool g_useIncomingECS; static shared_ptr g_initialProxyProtocolACL; static shared_ptr> g_initialProxyProtocolExceptions; +static shared_ptr g_initialOpenTelemetryConditions; // XXX shared ptr needed? boost::optional g_dns64Prefix{boost::none}; DNSName g_dns64PrefixReverse; unsigned int g_maxChainLength; @@ -2776,7 +2777,12 @@ static void recursorThread() else { t_proxyMapping = nullptr; } - + if (g_OTConditions) { + t_OTConditions = make_unique(*g_OTConditions); + } + else { + t_OTConditions = nullptr; + } if (threadInfo.isHandler()) { if (!primeHints()) { threadInfo.setExitCode(EXIT_FAILURE); diff --git a/pdns/recursordist/rec-rust-lib/cxxsupport.cc b/pdns/recursordist/rec-rust-lib/cxxsupport.cc index 6be5d2432e..ba9b0be873 100644 --- a/pdns/recursordist/rec-rust-lib/cxxsupport.cc +++ b/pdns/recursordist/rec-rust-lib/cxxsupport.cc @@ -1338,11 +1338,17 @@ void fromRustToOTTraceConditions(const rust::Vecadd(DNSName(std::string(qname))); + } + if (!setting.qtypes.empty()) { + condition.d_qtypes = std::unordered_set(); } for (const auto& qtype : setting.qtypes) { - condition.d_qtypes.insert(QType::chartocode(std::string(qtype).data())); + condition.d_qtypes->insert(QType::chartocode(std::string(qtype).data())); } if (setting.qid != std::numeric_limits::max()) { condition.d_qid = setting.qid;