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;
}
/**
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
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);
}
return false;
}
+static bool match(const std::unique_ptr<OpenTelemetryTraceConditions>& 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
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) {
struct OpenTelemetryTraceCondition
{
- SuffixMatchTree<bool> d_qnames;
- std::unordered_set<QType> d_qtypes;
+ std::optional<SuffixMatchNode> d_qnames;
+ std::optional<std::unordered_set<QType>> d_qtypes;
std::optional<uint16_t> d_qid;
bool d_edns_option_required{false};
bool d_traceid_only{false};
bool g_useIncomingECS;
static shared_ptr<NetmaskGroup> g_initialProxyProtocolACL;
static shared_ptr<std::set<ComboAddress>> g_initialProxyProtocolExceptions;
+static shared_ptr<OpenTelemetryTraceConditions> g_initialOpenTelemetryConditions; // XXX shared ptr needed?
boost::optional<ComboAddress> g_dns64Prefix{boost::none};
DNSName g_dns64PrefixReverse;
unsigned int g_maxChainLength;
else {
t_proxyMapping = nullptr;
}
-
+ if (g_OTConditions) {
+ t_OTConditions = make_unique<OpenTelemetryTraceConditions>(*g_OTConditions);
+ }
+ else {
+ t_OTConditions = nullptr;
+ }
if (threadInfo.isHandler()) {
if (!primeHints()) {
threadInfo.setExitCode(EXIT_FAILURE);
{
for (const auto& setting : settings) {
OpenTelemetryTraceCondition condition;
+ if (!setting.qnames.empty()) {
+ condition.d_qnames = SuffixMatchNode();
+ }
for (const auto& qname : setting.qnames) {
- condition.d_qnames.add(DNSName(std::string(qname)), true);
+ condition.d_qnames->add(DNSName(std::string(qname)));
+ }
+ if (!setting.qtypes.empty()) {
+ condition.d_qtypes = std::unordered_set<QType>();
}
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<uint32_t>::max()) {
condition.d_qid = setting.qid;