struct EDNSOTTraceRecord
{
- // 1 byte version, 1 byte reserved/alignment, 16 bytes traceid, optional 8 bytes spanid
- static constexpr size_t fullSize = 1 + 1 + 16 + 8;
- static constexpr size_t sizeNoSpanID = 1 + 1 + 16;
+ // 1 byte version, 1 byte reserved, 16 bytes traceid, 8 bytes spanid, 1 byte flags
+ static constexpr size_t fullSize = 1 + 1 + 16 + 8 + 1;
static constexpr size_t traceIDOffset = 1 + 1;
- static constexpr size_t spanIDOffset = 1 + 1 + 16;
+ static constexpr size_t spanIDOffset = traceIDOffset + 16;
+ static constexpr size_t flagsOffset = spanIDOffset + 8;
EDNSOTTraceRecord(uint8_t* arg) :
data(arg) {}
{
std::copy(spanid.begin(), spanid.end(), &data[spanIDOffset]);
}
+ void setFlags(const uint8_t flags)
+ {
+ data[flagsOffset] = flags;
+ }
// NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic)
private:
uint8_t* data;
}
[[nodiscard]] bool getTraceID(TraceID& traceid) const
{
- if (size >= pdns::trace::EDNSOTTraceRecord::sizeNoSpanID) {
+ if (size == pdns::trace::EDNSOTTraceRecord::fullSize) {
std::copy(&data[EDNSOTTraceRecord::traceIDOffset], &data[EDNSOTTraceRecord::traceIDOffset + traceid.size()], traceid.begin());
return true;
}
[[nodiscard]] bool getSpanID(SpanID& spanid) const
{
if (size == pdns::trace::EDNSOTTraceRecord::fullSize) {
+ std::string x((char*)&data[EDNSOTTraceRecord::spanIDOffset], spanid.size());
std::copy(&data[EDNSOTTraceRecord::spanIDOffset], &data[EDNSOTTraceRecord::spanIDOffset + spanid.size()], spanid.begin());
return true;
}
return false;
}
+ [[nodiscard]] bool getFlags(uint8_t& flags) const
+ {
+ if (size == pdns::trace::EDNSOTTraceRecord::fullSize) {
+ flags = data[EDNSOTTraceRecord::flagsOffset];
+ return true;
+ }
+ return false;
+ }
// NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic)
private:
const uint8_t* const data;
return qclass.toString();
}
-using OpenTelemetryData = std::optional<std::pair<pdns::trace::TraceID, pdns::trace::SpanID>>;
+using OpenTelemetryData = std::optional<std::tuple<pdns::trace::TraceID, pdns::trace::SpanID, uint8_t>>;
static std::unordered_set<uint16_t> s_expectedIDs;
opts.emplace_back(EDNSOptionCode::COOKIE, cookieOpt.makeOptString());
}
if (otids) {
- const auto traceid = otids->first;
- const auto spanid = otids->second;
+ const auto traceid = std::get<0>(*otids);
+ const auto spanid = std::get<1>(*otids);
+ const auto flags = std::get<2>(*otids);
std::array<uint8_t, pdns::trace::EDNSOTTraceRecord::fullSize> data{};
pdns::trace::EDNSOTTraceRecord record{data.data()};
record.setVersion(0);
record.setTraceID(traceid);
record.setSpanID(spanid);
+ record.setFlags(flags);
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);
auto traceIDArg = std::string(argv[++i]);
pdns::trace::TraceID traceid;
pdns::trace::SpanID spanid;
+ uint8_t traceflags = 0;
+ // Cannot set flags yet.
if (traceIDArg == "-") {
traceid.makeRandom();
spanid.makeRandom();
else {
auto traceIDStr = makeBytesFromHex(traceIDArg);
if (traceIDStr.size() > traceid.size() + spanid.size()) {
- cerr << "Maximum length of traceid plus spanid is " << traceid.size() + spanid.size()<< " bytes" << endl;
+ cerr << "Maximum length of traceid plus spanid is " << traceid.size() + spanid.size() << " bytes" << endl;
exit(EXIT_FAILURE);
}
- std::string spanidStr(traceIDStr.begin() + traceid.size(), traceIDStr.end());
+
+ std::string spanidStr;
+ if (traceIDStr.size() > traceid.size()) {
+ spanidStr = std::string(traceIDStr.begin() + traceid.size(), traceIDStr.end());
+ }
traceIDStr.resize(traceid.size());
pdns::trace::fill(traceid, traceIDStr);
if (spanidStr.empty()) {
pdns::trace::fill(spanid, spanidStr);
}
}
- otdata = std::make_pair(traceid, spanid);
+ otdata = std::make_tuple(traceid, spanid, traceflags);
}
else {
cerr << argv[i] << ": unknown argument" << endl;