if msg.HasField('ednsVersion'):
ednsVersion = "0x%08X" % socket.ntohl(msg.ednsVersion)
+ ede = "N/A"
+ if msg.HasField('ede'):
+ ede = str(msg.ede)
+ edeText = "N/A"
+ if msg.HasField('edeText'):
+ edeText = msg.edeText
+
openTelemetryData = "N/A"
if opentelemetryAvailable and msg.HasField('openTelemetryData'):
openTelemetryData = str(len(msg.openTelemetryData))
+ openTelemetryTraceID = "N/A"
+ if msg.HasField('openTelemetryTraceID'):
+ openTelemetryTraceID = binascii.hexlify(msg.openTelemetryTraceID)
+
print('[%s] %s of size %d: %s%s%s -> %s%s(%s) id: %d uuid: %s%s '
- 'requestorid: %s deviceid: %s devicename: %s serverid: %s nod: %s workerId: %s pcCacheHit: %s outgoingQueries: %s headerFlags: %s ednsVersion: %s openTelemetryData: len %s' %
+ 'requestorid: %s deviceid: %s devicename: %s serverid: %s nod: %s workerId: %s pcCacheHit: %s outgoingQueries: %s headerFlags: %s ednsVersion: %s ede: %s edeText: %s openTelemetryData: len %s otTraceID: %s' %
(datestr,
typestr,
msg.inBytes,
outgoingQs,
headerFlags,
ednsVersion,
- openTelemetryData))
+ ede,
+ edeText,
+ openTelemetryData,
+ openTelemetryTraceID))
for mt in msg.meta:
values = ''
optional uint32 headerFlags = 28; // Flags field in wire format, 16 bits used
optional uint32 ednsVersion = 29; // EDNS version and flags in wire format, see https://www.rfc-editor.org/rfc/rfc6891.html#section-6.1.3
optional bytes openTelemetryData = 30; // Protobuf encoded Open Telemetry Data, see https://github.com/open-telemetry/opentelemetry-proto/blob/main/opentelemetry/proto/trace/v1/trace.proto
+ optional uint32 ede = 31; // EDNS error code, actually 16 bits
+ optional string edeText = 32; // EDNS error text
+ optional bytes openTelemetryTraceID = 33; // OpenTelemetry TraceID
}
message PBDNSMessageList {
using TraceID = std::array<uint8_t, 16>;
using SpanID = std::array<uint8_t, 8>;
+constexpr TraceID s_emptyTraceID = {};
+
inline void random(TraceID& trace)
{
dns_random(trace.data(), trace.size());
headerFlags = 28,
ednsVersion = 29,
openTelemetryData = 30,
+ ede = 31,
+ edeText = 32,
+ openTelemetryTraceID = 33,
};
enum class QuestionField : protozero::pbf_tag_type
{
}
}
+ void setEDE(const uint16_t ede)
+ {
+ add_uint32(d_message, Field::ede, ede);
+ }
+
+ void setEDEText(const std::string edeText)
+ {
+ if (!edeText.empty()) {
+ add_string(d_message, Field::edeText, edeText);
+ }
+ }
+
+ void setOpenTelemtryTraceID(const std::array<uint8_t, 16>& traceID)
+ {
+ add_bytes(d_message, Field::openTelemetryTraceID, reinterpret_cast<const char*>(traceID.data()), traceID.size()); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast): it's the API
+ }
+
void startResponse()
{
d_response = protozero::pbf_writer{d_message, static_cast<protozero::pbf_tag_type>(Field::response)};
}
}
+ std::optional<EDNSExtendedError> eee;
if (haveEDNS) {
auto state = resolver.getValidationState();
if (comboWriter->d_extendedErrorCode || resolver.d_extendedError || (SyncRes::s_addExtendedResolutionDNSErrors && vStateIsBogus(state))) {
throw std::runtime_error("Bogus validation state not handled: " + vStateToString(state));
}
}
+ eee.emplace(EDNSExtendedError{static_cast<uint16_t>(code), std::move(extra)});
- EDNSExtendedError eee;
- eee.infoCode = static_cast<uint16_t>(code);
- eee.extraText = std::move(extra);
-
- if (packetWriter.size() < maxanswersize && (maxanswersize - packetWriter.size()) >= (EDNSOptionCodeSize + EDNSOptionLengthSize + sizeof(eee.infoCode) + eee.extraText.size())) {
- returnedEdnsOptions.emplace_back(EDNSOptionCode::EXTENDEDERROR, makeEDNSExtendedErrorOptString(eee));
+ if (packetWriter.size() < maxanswersize && (maxanswersize - packetWriter.size()) >= (EDNSOptionCodeSize + EDNSOptionLengthSize + sizeof(eee->infoCode) + eee->extraText.size())) {
+ returnedEdnsOptions.emplace_back(EDNSOptionCode::EXTENDEDERROR, makeEDNSExtendedErrorOptString(*eee));
}
}
pbMessage.setValidationState(resolver.getValidationState());
// See if we want to store the policyTags into the PC
addPolicyTagsToPBMessageIfNeeded(*comboWriter, pbMessage);
+ if (eee) {
+ pbMessage.setEDE(eee->infoCode);
+ pbMessage.setEDEText(eee->extraText);
+ }
// Take s snap of the current protobuf buffer state to store in the PC
pbDataForCache = boost::make_optional(RecursorPacketCache::PBData{
string otData = otTrace.encode();
pbMessage.setOpenTelemetryData(otData);
}
+ // Currently only set if an OT trace is generated
+ if (resolver.d_otTrace.trace_id != pdns::trace::s_emptyTraceID) {
+ pbMessage.setOpenTelemtryTraceID(resolver.d_otTrace.trace_id);
+ }
if (comboWriter->d_logResponse) {
protobufLogResponse(pbMessage);
}
RecursorPacketCache::OptPBData pbData{boost::none};
if (t_protobufServers.servers) {
if (logQuery && !(luaconfsLocal->protobufExportConfig.taggedOnly && policyTags.empty())) {
- protobufLogQuery(luaconfsLocal, uniqueId, source, destination, mappedSource, ednssubnet.getSource(), false, question.size(), qname, qtype, qclass, policyTags, requestorId, deviceId, deviceName, meta, ednsVersion, *dnsheader);
+ protobufLogQuery(luaconfsLocal, uniqueId, source, destination, mappedSource, ednssubnet.getSource(), false, question.size(), qname, qtype, qclass, policyTags, requestorId, deviceId, deviceName, meta, ednsVersion, *dnsheader, otTrace.trace_id);
}
}
return true;
}
-void protobufLogQuery(LocalStateHolder<LuaConfigItems>& luaconfsLocal, const boost::uuids::uuid& uniqueId, const ComboAddress& remote, const ComboAddress& local, const ComboAddress& mappedSource, const Netmask& ednssubnet, bool tcp, size_t len, const DNSName& qname, uint16_t qtype, uint16_t qclass, const std::unordered_set<std::string>& policyTags, const std::string& requestorId, const std::string& deviceId, const std::string& deviceName, const std::map<std::string, RecursorLua4::MetaValue>& meta, const boost::optional<uint32_t>& ednsVersion, const dnsheader& header)
+void protobufLogQuery(LocalStateHolder<LuaConfigItems>& luaconfsLocal, const boost::uuids::uuid& uniqueId, const ComboAddress& remote, const ComboAddress& local, const ComboAddress& mappedSource, const Netmask& ednssubnet, bool tcp, size_t len, const DNSName& qname, uint16_t qtype, uint16_t qclass, const std::unordered_set<std::string>& policyTags, const std::string& requestorId, const std::string& deviceId, const std::string& deviceName, const std::map<std::string, RecursorLua4::MetaValue>& meta, const boost::optional<uint32_t>& ednsVersion, const dnsheader& header, const pdns::trace::TraceID& traceID)
{
auto log = g_slog->withName("pblq");
if (ednsVersion) {
msg.setEDNSVersion(*ednsVersion);
}
+ if (traceID != pdns::trace::s_emptyTraceID) {
+ msg.setOpenTelemtryTraceID(traceID);
+ }
std::string strMsg(msg.finishAndMoveBuf());
for (auto& server : *t_protobufServers.servers) {
auto trace = pdns::trace::TracesData::boilerPlate("rec", qname.toLogString() + '/' + qtype.toString(), eventTrace.convertToOT(otTrace));
pbMessage.setOpenTelemetryData(trace.encode());
}
+ if (otTrace.trace_id != pdns::trace::s_emptyTraceID) {
+ pbMessage.setOpenTelemtryTraceID(otTrace.trace_id);
+ }
pbMessage.addPolicyTags(policyTags);
protobufLogResponse(pbMessage);
#endif
void getQNameAndSubnet(const std::string& question, DNSName* dnsname, uint16_t* qtype, uint16_t* qclass,
bool& foundECS, EDNSSubnetOpts* ednssubnet, EDNSOptionViewMap* options, boost::optional<uint32_t>& ednsVersion);
-void protobufLogQuery(LocalStateHolder<LuaConfigItems>& luaconfsLocal, const boost::uuids::uuid& uniqueId, const ComboAddress& remote, const ComboAddress& local, const ComboAddress& mappedSource, const Netmask& ednssubnet, bool tcp, size_t len, const DNSName& qname, uint16_t qtype, uint16_t qclass, const std::unordered_set<std::string>& policyTags, const std::string& requestorId, const std::string& deviceId, const std::string& deviceName, const std::map<std::string, RecursorLua4::MetaValue>& meta, const boost::optional<uint32_t>& ednsVersion, const dnsheader& header);
+void protobufLogQuery(LocalStateHolder<LuaConfigItems>& luaconfsLocal, const boost::uuids::uuid& uniqueId, const ComboAddress& remote, const ComboAddress& local, const ComboAddress& mappedSource, const Netmask& ednssubnet, bool tcp, size_t len, const DNSName& qname, uint16_t qtype, uint16_t qclass, const std::unordered_set<std::string>& policyTags, const std::string& requestorId, const std::string& deviceId, const std::string& deviceName, const std::map<std::string, RecursorLua4::MetaValue>& meta, const boost::optional<uint32_t>& ednsVersion, const dnsheader& header, const pdns::trace::TraceID& traceID);
bool isAllowNotifyForZone(DNSName qname);
bool checkForCacheHit(bool qnameParsed, unsigned int tag, const string& data,
DNSName& qname, uint16_t& qtype, uint16_t& qclass,
{
try {
if (logQuery && !(luaconfsLocal->protobufExportConfig.taggedOnly && comboWriter->d_policyTags.empty())) {
- protobufLogQuery(luaconfsLocal, comboWriter->d_uuid, comboWriter->d_source, comboWriter->d_destination, comboWriter->d_mappedSource, comboWriter->d_ednssubnet.getSource(), true, conn->qlen, qname, qtype, qclass, comboWriter->d_policyTags, comboWriter->d_requestorId, comboWriter->d_deviceId, comboWriter->d_deviceName, comboWriter->d_meta, ednsVersion, *dnsheader);
+ protobufLogQuery(luaconfsLocal, comboWriter->d_uuid, comboWriter->d_source, comboWriter->d_destination, comboWriter->d_mappedSource, comboWriter->d_ednssubnet.getSource(), true, conn->qlen, qname, qtype, qclass, comboWriter->d_policyTags, comboWriter->d_requestorId, comboWriter->d_deviceId, comboWriter->d_deviceName, comboWriter->d_meta, ednsVersion, *dnsheader, comboWriter->d_otTrace.trace_id);
}
}
catch (const std::exception& e) {