struct EDNSOptionCode
{
// Temporary code assigned for OpenTelemetry TraceID and SpanID
- enum EDNSOptionCodeEnum : uint16_t {NSID=3, DAU=5, DHU=6, N3U=7, ECS=8, EXPIRE=9, COOKIE=10, TCPKEEPALIVE=11, PADDING=12, CHAIN=13, KEYTAG=14, EXTENDEDERROR=15, OTTRACEID=65500, OTSPANID=65501};
+ enum EDNSOptionCodeEnum : uint16_t {NSID=3, DAU=5, DHU=6, N3U=7, ECS=8, EXPIRE=9, COOKIE=10, TCPKEEPALIVE=11, PADDING=12, CHAIN=13, KEYTAG=14, EXTENDEDERROR=15, OTTRACEIDS=65500};
};
/* extract the position (relative to the optRR pointer!) and size of a specific EDNS0 option from a pointer on the beginning rdLen of the OPT RR */
// parent_span_id gets set from edns options (if available and well-formed, otherwise it remains cleared (no parent))
// span_id gets inited randomly
bool traceidset = false;
- if (const auto& option = map.find(EDNSOptionCode::OTTRACEID); option != map.end()) {
+ const auto traceIDSize = span.trace_id.size();
+
+ if (const auto& option = map.find(EDNSOptionCode::OTTRACEIDS); option != map.end()) {
if (option->second.values.size() > 0) {
- if (option->second.values.at(0).size == span.trace_id.size()) {
+ if (option->second.values.at(0).size >= traceIDSize) {
traceidset = true;
- pdns::trace::fill(span.trace_id, option->second.values.at(0).content, span.trace_id.size());
+ pdns::trace::fill(span.trace_id, option->second.values.at(0).content, traceIDSize);
+ }
+ if (option->second.values.at(0).size == traceIDSize + span.parent_span_id.size()) {
+ pdns::trace::fill(span.parent_span_id, &option->second.values.at(0).content[traceIDSize], span.parent_span_id.size()); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) it's the API
}
}
}
if (!traceidset) {
random(span.trace_id);
}
- if (const auto& option = map.find(EDNSOptionCode::OTSPANID); option != map.end()) {
- if (option->second.values.size() > 0) {
- if (option->second.values.at(0).size == span.parent_span_id.size()) {
- pdns::trace::fill(span.parent_span_id, option->second.values.at(0).content, span.parent_span_id.size());
- }
- }
- // Empty parent span id indicated the client did not set one
- }
+ // Empty parent span id indicated the client did not set one, thats fine
random(span.span_id);
}
opts.emplace_back(EDNSOptionCode::COOKIE, cookieOpt.makeOptString());
}
if (otids) {
- opts.emplace_back(EDNSOptionCode::OTTRACEID, std::string_view(reinterpret_cast<const char*>(otids->first.data()), otids->first.size())); // NOLINT
- opts.emplace_back(EDNSOptionCode::OTSPANID, std::string_view(reinterpret_cast<const char*>(otids->second.data()), otids->second.size())); // NOLINT
+ const auto traceid = otids->first;
+ const auto spanid = otids->second;
+ std::array<uint8_t, traceid.size() + spanid.size()> data{};
+ std::copy(traceid.begin(), traceid.end(), data.begin());
+ std::copy(spanid.begin(), spanid.end(), data.begin() + traceid.size());
+ opts.emplace_back(EDNSOptionCode::OTTRACEIDS, std::string_view(reinterpret_cast<const char*>(data.data()), data.size())); // NOLINT
}
pw.addOpt(bufsize, 0, dnssec ? EDNSOpts::DNSSECOK : 0, opts);
pw.commit();