#include "dnsdist-protobuf.hh"
#include "protozero.hh"
-DNSDistProtoBufMessage::DNSDistProtoBufMessage(const DNSQuestion& dq): d_dq(dq), d_type(1)
+DNSDistProtoBufMessage::DNSDistProtoBufMessage(const DNSQuestion& dq): d_dq(dq), d_type(pdns::ProtoZero::Message::MessageType::DNSQueryType)
{
}
-DNSDistProtoBufMessage::DNSDistProtoBufMessage(const DNSResponse& dr, bool includeCNAME): d_dq(dr), d_dr(&dr), d_type(2), d_includeCNAME(includeCNAME)
+DNSDistProtoBufMessage::DNSDistProtoBufMessage(const DNSResponse& dr, bool includeCNAME): d_dq(dr), d_dr(&dr), d_type(pdns::ProtoZero::Message::MessageType::DNSResponseType), d_includeCNAME(includeCNAME)
{
}
d_rcode = rcode;
}
-void DNSDistProtoBufMessage::setType(uint32_t type)
+void DNSDistProtoBufMessage::setType(pdns::ProtoZero::Message::MessageType type)
{
d_type = type;
}
void setRequestorPort(uint16_t port);
void setResponderPort(uint16_t port);
void setResponseCode(uint8_t rcode);
- void setType(uint32_t type);
+ void setType(pdns::ProtoZero::Message::MessageType type);
void setBytes(size_t bytes);
void setTime(time_t sec, uint32_t usec);
void setQueryTime(time_t sec, uint32_t usec);
boost::optional<size_t> d_bytes{boost::none};
boost::optional<uint8_t> d_rcode{boost::none};
- uint32_t d_type{1};
+ pdns::ProtoZero::Message::MessageType d_type{pdns::ProtoZero::Message::MessageType::DNSQueryType};
bool d_includeCNAME{false};
};
luaCtx.registerFunction<void(DNSDistProtoBufMessage::*)(boost::optional <time_t> sec, boost::optional <uint32_t> uSec)>("setProtobufResponseType",
[](DNSDistProtoBufMessage& message, boost::optional <time_t> sec, boost::optional <uint32_t> uSec) {
- message.setType(2);
+ message.setType(pdns::ProtoZero::Message::MessageType::DNSResponseType);
message.setQueryTime(sec ? *sec : 0, uSec ? *uSec : 0);
});
pbBuffer.clear();
pdns::ProtoZero::Message pbMessage(pbBuffer);
- pbMessage.setType(dh->qr ? 2 : 1);
+ pbMessage.setType(dh->qr ? pdns::ProtoZero::Message::MessageType::DNSResponseType : pdns::ProtoZero::Message::MessageType::DNSQueryType);
pbMessage.setRequest(uniqueId, requestor, responder, qname, qtype, qclass, dh->id, false, pr.d_len);
pbMessage.setTime(pr.d_pheader.ts.tv_sec, pr.d_pheader.ts.tv_usec);
static thread_local std::string buffer;
buffer.clear();
pdns::ProtoZero::Message m{buffer};
- m.setType(3);
+ m.setType(pdns::ProtoZero::Message::MessageType::DNSOutgoingQueryType);
m.setMessageIdentity(uuid);
m.setSocketFamily(ip.sin4.sin_family);
m.setSocketProtocol(doTCP);
static thread_local std::string buffer;
buffer.clear();
pdns::ProtoZero::RecMessage m{buffer};
- m.setType(4);
+ m.setType(pdns::ProtoZero::Message::MessageType::DNSIncomingResponseType);
m.setMessageIdentity(uuid);
m.setSocketFamily(ip.sin4.sin_family);
m.setSocketProtocol(doTCP);
requestor.setPort(remote.getPort());
pdns::ProtoZero::RecMessage m{128, std::string::size_type(policyTags.empty() ? 0 : 64)}; // It's a guess
- m.setType(1);
+ m.setType(pdns::ProtoZero::Message::MessageType::DNSQueryType);
m.setRequest(uniqueId, requestor, local, qname, qtype, qclass, id, tcp, len);
m.setServerIdentity(SyncRes::s_serverID);
m.setEDNSSubnet(ednssubnet, ednssubnet.isIPv4() ? maskV4 : maskV6);
if (pbData) {
// We take the inmutable string from the cache and are appending a few values
} else {
- pbMessage.setType(2); // Response
+ pbMessage.setType(pdns::ProtoZero::Message::MessageType::DNSResponseType);
pbMessage.setServerIdentity(SyncRes::s_serverID);
}
void pdns::ProtoZero::Message::setResponse(const DNSName& qname, uint16_t qtype, uint16_t qclass)
{
- setType(2);
+ setType(pdns::ProtoZero::Message::MessageType::DNSResponseType);
setQuestion(qname, qtype, qclass);
}
addRR(rrname, ah.d_type, ah.d_class, ah.d_ttl, blob);
} else if (ah.d_type == QType::CNAME && includeCNAME) {
- protozero::pbf_writer pbf_rr{d_response, 2};
+ protozero::pbf_writer pbf_rr{d_response, static_cast<protozero::pbf_tag_type>(pdns::ProtoZero::Message::ResponseField::rrs)};
- encodeDNSName(pbf_rr, d_buffer, 1, rrname);
- pbf_rr.add_uint32(2, ah.d_type);
- pbf_rr.add_uint32(3, ah.d_class);
- pbf_rr.add_uint32(4, ah.d_ttl);
+ encodeDNSName(pbf_rr, d_buffer, static_cast<protozero::pbf_tag_type>(pdns::ProtoZero::Message::RRField::name), rrname);
+ pbf_rr.add_uint32(static_cast<protozero::pbf_tag_type>(pdns::ProtoZero::Message::RRField::type), ah.d_type);
+ pbf_rr.add_uint32(static_cast<protozero::pbf_tag_type>(pdns::ProtoZero::Message::RRField::class_), ah.d_class);
+ pbf_rr.add_uint32(static_cast<protozero::pbf_tag_type>(pdns::ProtoZero::Message::RRField::ttl), ah.d_ttl);
DNSName target;
pr.xfrName(target, true);
- encodeDNSName(pbf_rr, d_buffer, 5, target);
+ encodeDNSName(pbf_rr, d_buffer, static_cast<protozero::pbf_tag_type>(pdns::ProtoZero::Message::RRField::rdata), target);
}
else {
pr.xfrBlob(blob);
void pdns::ProtoZero::Message::addRR(const DNSName& name, uint16_t uType, uint16_t uClass, uint32_t uTTL, const std::string& blob)
{
- protozero::pbf_writer pbf_rr{d_response, 2};
- encodeDNSName(pbf_rr, d_buffer, 1, name);
- pbf_rr.add_uint32(2, uType);
- pbf_rr.add_uint32(3, uClass);
- pbf_rr.add_uint32(4, uTTL);
- pbf_rr.add_string(5, blob);
+ protozero::pbf_writer pbf_rr{d_response, static_cast<protozero::pbf_tag_type>(pdns::ProtoZero::Message::ResponseField::rrs)};
+ encodeDNSName(pbf_rr, d_buffer, static_cast<protozero::pbf_tag_type>(pdns::ProtoZero::Message::RRField::name), name);
+ pbf_rr.add_uint32(static_cast<protozero::pbf_tag_type>(pdns::ProtoZero::Message::RRField::type), uType);
+ pbf_rr.add_uint32(static_cast<protozero::pbf_tag_type>(pdns::ProtoZero::Message::RRField::class_), uClass);
+ pbf_rr.add_uint32(static_cast<protozero::pbf_tag_type>(pdns::ProtoZero::Message::RRField::ttl), uTTL);
+ pbf_rr.add_string(static_cast<protozero::pbf_tag_type>(pdns::ProtoZero::Message::RRField::rdata), blob);
}
namespace ProtoZero {
class Message {
public:
+ enum class MessageType : int32_t { DNSQueryType = 1, DNSResponseType = 2, DNSOutgoingQueryType = 3, DNSIncomingResponseType = 4 };
+ enum class Field : protozero::pbf_tag_type { type = 1, messageId = 2, serverIdentity = 3, socketFamily = 4, socketProtocol = 5, from = 6, to = 7, inBytes = 8, timeSec = 9, timeUsec = 10, id = 11, question = 12, response = 13, originalRequestorSubnet = 14, requestorId = 15, initialRequestId = 16, deviceId = 17, newlyObservedDomain = 18, deviceName = 19, fromPort = 20, toPort = 21 };
+ enum class QuestionField : protozero::pbf_tag_type { qName = 1, qType = 2, qClass = 3};
+ enum class ResponseField : protozero::pbf_tag_type { rcode = 1, rrs = 2, appliedPolicy = 3, tags = 4, queryTimeSec = 5, queryTimeUsec = 6, appliedPolicyType = 7, appliedPolicyTrigger = 8, appliedPolicyHit = 9 };
+ enum class RRField : protozero::pbf_tag_type { name = 1, type = 2, class_ = 3, ttl = 4, rdata = 5, udr = 6 };
+
Message(std::string& buffer): d_buffer(buffer), d_message{d_buffer}
{
}
void setRequest(const boost::uuids::uuid& uniqueId, const ComboAddress& requestor, const ComboAddress& local, const DNSName& qname, uint16_t qtype, uint16_t qclass, uint16_t id, bool tcp, size_t len);
void setResponse(const DNSName& qname, uint16_t qtype, uint16_t qclass);
- void setType(uint32_t mtype)
+ void setType(MessageType mtype)
{
- d_message.add_enum(1, mtype);
+ add_enum(d_message, Field::type, static_cast<int32_t>(mtype));
}
void setMessageIdentity(const boost::uuids::uuid& uniqueId)
{
- d_message.add_bytes(2, reinterpret_cast<const char*>(uniqueId.begin()), uniqueId.size());
+ add_bytes(d_message, Field::messageId, reinterpret_cast<const char*>(uniqueId.begin()), uniqueId.size());
}
void setServerIdentity(const std::string& serverIdentity)
{
- d_message.add_bytes(3, serverIdentity.data(), serverIdentity.length());
+ add_bytes(d_message, Field::serverIdentity, serverIdentity.data(), serverIdentity.length());
}
void setSocketFamily(int family)
{
- d_message.add_enum(4, family == AF_INET ? 1 : 2);
+ add_enum(d_message, Field::socketFamily, family == AF_INET ? 1 : 2);
}
void setSocketProtocol(bool tcp)
{
- d_message.add_enum(5, tcp ? 2 : 1);
+ add_enum(d_message, Field::socketProtocol, tcp ? 2 : 1);
}
void setFrom(const ComboAddress& ca)
{
- encodeComboAddress(6, ca);
+ encodeComboAddress(static_cast<protozero::pbf_tag_type>(Field::from), ca);
}
void setTo(const ComboAddress& ca)
{
- encodeComboAddress(7, ca);
+ encodeComboAddress(static_cast<protozero::pbf_tag_type>(Field::to), ca);
}
void setInBytes(uint64_t len)
{
if (len) {
- d_message.add_uint64(8, len);
+ add_uint64(d_message, Field::inBytes, len);
}
}
void setTime(time_t sec, uint32_t usec)
{
- // timeSec
- d_message.add_uint32(9, sec);
- // timeUsec
- d_message.add_uint32(10, usec);
+ add_uint32(d_message, Field::timeSec, sec);
+ add_uint32(d_message, Field::timeUsec, usec);
}
void setId(uint16_t id)
{
- d_message.add_uint32(11, ntohs(id));
+ add_uint32(d_message, Field::id, ntohs(id));
}
void setQuestion(const DNSName& qname, uint16_t qtype, uint16_t qclass)
{
- protozero::pbf_writer pbf_question{d_message, 12};
- encodeDNSName(pbf_question, d_buffer, 1, qname);
- pbf_question.add_uint32(2, qtype);
- pbf_question.add_uint32(3, qclass);
+ protozero::pbf_writer pbf_question{d_message, static_cast<protozero::pbf_tag_type>(Field::question)};
+ encodeDNSName(pbf_question, d_buffer, static_cast<protozero::pbf_tag_type>(QuestionField::qName), qname);
+ pbf_question.add_uint32(static_cast<protozero::pbf_tag_type>(QuestionField::qType), qtype);
+ pbf_question.add_uint32(static_cast<protozero::pbf_tag_type>(QuestionField::qClass), qclass);
}
void setEDNSSubnet(const Netmask& nm, uint8_t mask)
{
- encodeNetmask(14, nm, mask);
+ encodeNetmask(static_cast<protozero::pbf_tag_type>(Field::originalRequestorSubnet), nm, mask);
}
void setRequestorId(const std::string& req)
{
if (!req.empty()) {
- d_message.add_string(15, req);
+ add_string(d_message, Field::requestorId, req);
}
}
void setInitialRequestID(const boost::uuids::uuid& uniqueId)
{
- d_message.add_bytes(16, reinterpret_cast<const char*>(uniqueId.begin()), uniqueId.size());
+ add_bytes(d_message, Field::initialRequestId, reinterpret_cast<const char*>(uniqueId.begin()), uniqueId.size());
}
void setDeviceId(const std::string& id)
{
if (!id.empty()) {
- d_message.add_string(17, id);
+ add_string(d_message, Field::deviceId, id);
}
}
void setNewlyObservedDomain(bool nod)
{
- d_message.add_bool(18, nod);
+ add_bool(d_message, Field::newlyObservedDomain, nod);
}
void setDeviceName(const std::string& name)
{
if (!name.empty()) {
- d_message.add_string(19, name);
+ add_string(d_message, Field::deviceName, name);
}
}
void setFromPort(in_port_t port)
{
- d_message.add_uint32(20, port);
+ add_uint32(d_message, Field::fromPort, port);
}
void setToPort(in_port_t port)
{
- d_message.add_uint32(21, port);
+ add_uint32(d_message, Field::toPort, port);
}
void startResponse()
{
- d_response = protozero::pbf_writer{d_message, 13};
+ d_response = protozero::pbf_writer{d_message, static_cast<protozero::pbf_tag_type>(Field::response)};
}
void commitResponse()
void setResponseCode(uint8_t rcode)
{
- d_response.add_uint32(1, rcode);
+ d_response.add_uint32(static_cast<protozero::pbf_tag_type>(ResponseField::rcode), rcode);
}
void setNetworkErrorResponseCode()
{
/* special code meaning 'network error', like a timeout */
- d_response.add_uint32(1, 65536);
+ d_response.add_uint32(static_cast<protozero::pbf_tag_type>(ResponseField::rcode), 65536);
}
void setAppliedPolicy(const std::string& policy)
{
- d_response.add_string(3, policy);
+ d_response.add_string(static_cast<protozero::pbf_tag_type>(ResponseField::appliedPolicy), policy);
}
void addPolicyTags(const std::unordered_set<std::string>& tags)
{
for (const auto& tag : tags) {
- d_response.add_string(4, tag);
+ addPolicyTag(tag);
}
}
void addPolicyTag(const string& tag)
{
- d_response.add_string(4, tag);
+ d_response.add_string(static_cast<protozero::pbf_tag_type>(ResponseField::tags), tag);
}
void setQueryTime(uint32_t sec, uint32_t usec)
{
- d_response.add_uint32(5, sec);
- d_response.add_uint32(6, usec);
+ d_response.add_uint32(static_cast<protozero::pbf_tag_type>(ResponseField::queryTimeSec), sec);
+ d_response.add_uint32(static_cast<protozero::pbf_tag_type>(ResponseField::queryTimeUsec), usec);
}
void addRRsFromPacket(const char* packet, const size_t len, bool includeCNAME=false);
void encodeNetmask(protozero::pbf_tag_type type, const Netmask& subnet, uint8_t mask);
void encodeDNSName(protozero::pbf_writer& pbf, std::string& buffer, protozero::pbf_tag_type type, const DNSName& name);
+ static void add_enum(protozero::pbf_writer& writer, Field type, int32_t value)
+ {
+ writer.add_enum(static_cast<protozero::pbf_tag_type>(type), value);
+ }
+
+ static void add_bool(protozero::pbf_writer& writer, Field type, bool value)
+ {
+ writer.add_bool(static_cast<protozero::pbf_tag_type>(type), value);
+ }
+
+ static void add_uint32(protozero::pbf_writer& writer, Field type, uint32_t value)
+ {
+ writer.add_uint32(static_cast<protozero::pbf_tag_type>(type), value);
+ }
+
+ static void add_uint64(protozero::pbf_writer& writer, Field type, uint64_t value)
+ {
+ writer.add_uint64(static_cast<protozero::pbf_tag_type>(type), value);
+ }
+
+ static void add_bytes(protozero::pbf_writer& writer, Field type, const char* data, size_t len)
+ {
+ writer.add_bytes(static_cast<protozero::pbf_tag_type>(type), data, len);
+ }
+
+ static void add_string(protozero::pbf_writer& writer, Field type, const std::string& str)
+ {
+ writer.add_string(static_cast<protozero::pbf_tag_type>(type), str);
+ }
+
+
std::string& d_buffer;
protozero::pbf_writer d_message;
protozero::pbf_writer d_response;
return;
}
- protozero::pbf_writer pbf_rr{d_response, 2};
+ protozero::pbf_writer pbf_rr{d_response, static_cast<protozero::pbf_tag_type>(pdns::ProtoZero::Message::ResponseField::rrs)};
- encodeDNSName(pbf_rr, d_rspbuf, 1, record.d_name);
- pbf_rr.add_uint32(2, record.d_type);
- pbf_rr.add_uint32(3, record.d_class);
- pbf_rr.add_uint32(4, record.d_ttl);
+ encodeDNSName(pbf_rr, d_rspbuf, static_cast<protozero::pbf_tag_type>(pdns::ProtoZero::Message::RRField::name), record.d_name);
+ pbf_rr.add_uint32(static_cast<protozero::pbf_tag_type>(pdns::ProtoZero::Message::RRField::type), record.d_type);
+ pbf_rr.add_uint32(static_cast<protozero::pbf_tag_type>(pdns::ProtoZero::Message::RRField::class_), record.d_class);
+ pbf_rr.add_uint32(static_cast<protozero::pbf_tag_type>(pdns::ProtoZero::Message::RRField::ttl), record.d_ttl);
switch (record.d_type) {
case QType::A: {
const auto& content = dynamic_cast<const ARecordContent&>(*(record.d_content));
ComboAddress data = content.getCA();
- pbf_rr.add_bytes(5, reinterpret_cast<const char*>(&data.sin4.sin_addr.s_addr), sizeof(data.sin4.sin_addr.s_addr));
+ pbf_rr.add_bytes(static_cast<protozero::pbf_tag_type>(pdns::ProtoZero::Message::RRField::rdata), reinterpret_cast<const char*>(&data.sin4.sin_addr.s_addr), sizeof(data.sin4.sin_addr.s_addr));
break;
}
case QType::AAAA: {
const auto& content = dynamic_cast<const AAAARecordContent&>(*(record.d_content));
ComboAddress data = content.getCA();
- pbf_rr.add_bytes(5, reinterpret_cast<const char*>(&data.sin6.sin6_addr.s6_addr), sizeof(data.sin6.sin6_addr.s6_addr));
+ pbf_rr.add_bytes(static_cast<protozero::pbf_tag_type>(pdns::ProtoZero::Message::RRField::rdata), reinterpret_cast<const char*>(&data.sin6.sin6_addr.s6_addr), sizeof(data.sin6.sin6_addr.s6_addr));
break;
}
case QType::CNAME: {
const auto& content = dynamic_cast<const CNAMERecordContent&>(*(record.d_content));
- pbf_rr.add_string(5, content.getTarget().toString());
+ pbf_rr.add_string(static_cast<protozero::pbf_tag_type>(pdns::ProtoZero::Message::RRField::rdata), content.getTarget().toString());
break;
}
case QType::TXT: {
const auto& content = dynamic_cast<const TXTRecordContent&>(*(record.d_content));
- pbf_rr.add_string(5, content.d_text);
+ pbf_rr.add_string(static_cast<protozero::pbf_tag_type>(pdns::ProtoZero::Message::RRField::rdata), content.d_text);
break;
}
case QType::NS: {
const auto& content = dynamic_cast<const NSRecordContent&>(*(record.d_content));
- pbf_rr.add_string(5, content.getNS().toString());
+ pbf_rr.add_string(static_cast<protozero::pbf_tag_type>(pdns::ProtoZero::Message::RRField::rdata), content.getNS().toString());
break;
}
case QType::PTR: {
const auto& content = dynamic_cast<const PTRRecordContent&>(*(record.d_content));
- pbf_rr.add_string(5, content.getContent().toString());
+ pbf_rr.add_string(static_cast<protozero::pbf_tag_type>(pdns::ProtoZero::Message::RRField::rdata), content.getContent().toString());
break;
}
case QType::MX: {
const auto& content = dynamic_cast<const MXRecordContent&>(*(record.d_content));
- pbf_rr.add_string(5, content.d_mxname.toString());
+ pbf_rr.add_string(static_cast<protozero::pbf_tag_type>(pdns::ProtoZero::Message::RRField::rdata), content.d_mxname.toString());
break;
}
case QType::SPF: {
const auto& content = dynamic_cast<const SPFRecordContent&>(*(record.d_content));
- pbf_rr.add_string(5, content.getText());
+ pbf_rr.add_string(static_cast<protozero::pbf_tag_type>(pdns::ProtoZero::Message::RRField::rdata), content.getText());
break;
}
case QType::SRV: {
const auto& content = dynamic_cast<const SRVRecordContent&>(*(record.d_content));
- pbf_rr.add_string(5, content.d_target.toString());
+ pbf_rr.add_string(static_cast<protozero::pbf_tag_type>(pdns::ProtoZero::Message::RRField::rdata), content.d_target.toString());
break;
}
default:
break;
}
#ifdef NOD_ENABLED
- pbf_rr.add_bool(6, udr);
+ pbf_rr.add_bool(static_cast<protozero::pbf_tag_type>(pdns::ProtoZero::Message::RRField::udr), udr);
pbf_rr.commit();
// Save the offset of the byte containing the just added bool. We can do this since
std::string&& finishAndMoveBuf()
{
if (!d_rspbuf.empty()) {
- d_message.add_message(13, d_rspbuf);
+ d_message.add_message(static_cast<protozero::pbf_tag_type>(Field::response), d_rspbuf);
}
return std::move(d_msgbuf);
}
default:
throw std::runtime_error("Unsupported protobuf policy type");
}
- d_response.add_uint32(7, p);
+ d_response.add_uint32(static_cast<protozero::pbf_tag_type>(ResponseField::appliedPolicyType), p);
}
void setAppliedPolicyTrigger(const DNSName& trigger)
{
- encodeDNSName(d_response, d_rspbuf, 8, trigger);
+ encodeDNSName(d_response, d_rspbuf, static_cast<protozero::pbf_tag_type>(ResponseField::appliedPolicyTrigger), trigger);
}
void setAppliedPolicyHit(const std::string& hit)
{
- d_response.add_string(9, hit);
+ d_response.add_string(static_cast<protozero::pbf_tag_type>(ResponseField::appliedPolicyHit), hit);
}
#ifdef NOD_ENABLED