summaryrefslogtreecommitdiffstats
path: root/dnsdist-protobuf.cc
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--dnsdist-protobuf.cc213
1 files changed, 118 insertions, 95 deletions
diff --git a/dnsdist-protobuf.cc b/dnsdist-protobuf.cc
index c38529c..30445ed 100644
--- a/dnsdist-protobuf.cc
+++ b/dnsdist-protobuf.cc
@@ -27,11 +27,13 @@
#include "dnsdist-protobuf.hh"
#include "protozero.hh"
-DNSDistProtoBufMessage::DNSDistProtoBufMessage(const DNSQuestion& dq): d_dq(dq), d_type(pdns::ProtoZero::Message::MessageType::DNSQueryType)
+DNSDistProtoBufMessage::DNSDistProtoBufMessage(const DNSQuestion& dnsquestion) :
+ d_dq(dnsquestion)
{
}
-DNSDistProtoBufMessage::DNSDistProtoBufMessage(const DNSResponse& dr, bool includeCNAME): d_dq(dr), d_dr(&dr), d_type(pdns::ProtoZero::Message::MessageType::DNSResponseType), d_includeCNAME(includeCNAME)
+DNSDistProtoBufMessage::DNSDistProtoBufMessage(const DNSResponse& dnsresponse, bool includeCNAME) :
+ d_dq(dnsresponse), d_dr(&dnsresponse), d_type(pdns::ProtoZero::Message::MessageType::DNSResponseType), d_includeCNAME(includeCNAME)
{
}
@@ -104,11 +106,14 @@ void DNSDistProtoBufMessage::addTag(const std::string& strValue)
d_additionalTags.push_back(strValue);
}
-void DNSDistProtoBufMessage::addMeta(const std::string& key, std::vector<std::string>&& values)
+void DNSDistProtoBufMessage::addMeta(const std::string& key, std::vector<std::string>&& strValues, const std::vector<int64_t>& intValues)
{
auto& entry = d_metaTags[key];
- for (auto& value : values) {
- entry.insert(std::move(value));
+ for (auto& value : strValues) {
+ entry.d_strings.insert(std::move(value));
+ }
+ for (const auto& value : intValues) {
+ entry.d_integers.insert(value);
}
}
@@ -146,6 +151,11 @@ void DNSDistProtoBufMessage::serialize(std::string& data) const
}
else if (distProto == dnsdist::Protocol::DoH) {
protocol = pdns::ProtoZero::Message::TransportProtocol::DoH;
+ m.setHTTPVersion(pdns::ProtoZero::Message::HTTPVersion::HTTP2);
+ }
+ else if (distProto == dnsdist::Protocol::DoH3) {
+ protocol = pdns::ProtoZero::Message::TransportProtocol::DoH;
+ m.setHTTPVersion(pdns::ProtoZero::Message::HTTPVersion::HTTP3);
}
else if (distProto == dnsdist::Protocol::DNSCryptUDP) {
protocol = pdns::ProtoZero::Message::TransportProtocol::DNSCryptUDP;
@@ -153,6 +163,9 @@ void DNSDistProtoBufMessage::serialize(std::string& data) const
else if (distProto == dnsdist::Protocol::DNSCryptTCP) {
protocol = pdns::ProtoZero::Message::TransportProtocol::DNSCryptTCP;
}
+ else if (distProto == dnsdist::Protocol::DoQ) {
+ protocol = pdns::ProtoZero::Message::TransportProtocol::DoQ;
+ }
m.setRequest(d_dq.ids.d_protoBufData && d_dq.ids.d_protoBufData->uniqueId ? *d_dq.ids.d_protoBufData->uniqueId : getUniqueID(), d_requestor ? *d_requestor : d_dq.ids.origRemote, d_responder ? *d_responder : d_dq.ids.origDest, d_question ? d_question->d_name : d_dq.ids.qname, d_question ? d_question->d_type : d_dq.ids.qtype, d_question ? d_question->d_class : d_dq.ids.qclass, d_dq.getHeader()->id, protocol, d_bytes ? *d_bytes : d_dq.getData().size());
@@ -210,8 +223,8 @@ void DNSDistProtoBufMessage::serialize(std::string& data) const
}
for (const auto& [key, values] : d_metaTags) {
- if (!values.empty()) {
- m.setMeta(key, values, {});
+ if (!values.d_strings.empty() || !values.d_integers.empty()) {
+ m.setMeta(key, values.d_strings, values.d_integers);
}
else {
/* the MetaValue field is _required_ to exist, even if we have no value */
@@ -255,14 +268,14 @@ ProtoBufMetaKey::ProtoBufMetaKey(const std::string& key)
throw std::runtime_error("Invalid ProtoBuf key '" + key + "'");
}
-std::vector<std::string> ProtoBufMetaKey::getValues(const DNSQuestion& dq) const
+std::vector<std::string> ProtoBufMetaKey::getValues(const DNSQuestion& dnsquestion) const
{
auto& idx = s_types.get<TypeTag>();
auto it = idx.find(d_type);
if (it == idx.end()) {
throw std::runtime_error("Trying to get the values of an unsupported type: " + std::to_string(static_cast<uint8_t>(d_type)));
}
- return (it->d_func)(dq, d_subKey, d_numericSubKey);
+ return (it->d_func)(dnsquestion, d_subKey, d_numericSubKey);
}
const std::string& ProtoBufMetaKey::getName() const
@@ -276,94 +289,104 @@ const std::string& ProtoBufMetaKey::getName() const
}
const ProtoBufMetaKey::TypeContainer ProtoBufMetaKey::s_types = {
- ProtoBufMetaKey::KeyTypeDescription{ "sni", Type::SNI, [](const DNSQuestion& dq, const std::string&, uint8_t) -> std::vector<std::string> { return {dq.sni}; }, false },
- ProtoBufMetaKey::KeyTypeDescription{ "pool", Type::Pool, [](const DNSQuestion& dq, const std::string&, uint8_t) -> std::vector<std::string> { return {dq.ids.poolName}; }, false },
- ProtoBufMetaKey::KeyTypeDescription{ "b64-content", Type::B64Content, [](const DNSQuestion& dq, const std::string&, uint8_t) -> std::vector<std::string> { const auto& data = dq.getData(); return {Base64Encode(std::string(data.begin(), data.end()))}; }, false },
+ ProtoBufMetaKey::KeyTypeDescription{"sni", Type::SNI, [](const DNSQuestion& dnsquestion, const std::string&, uint8_t) -> std::vector<std::string> { return {dnsquestion.sni}; }, false},
+ ProtoBufMetaKey::KeyTypeDescription{"pool", Type::Pool, [](const DNSQuestion& dnsquestion, const std::string&, uint8_t) -> std::vector<std::string> { return {dnsquestion.ids.poolName}; }, false},
+ ProtoBufMetaKey::KeyTypeDescription{"b64-content", Type::B64Content, [](const DNSQuestion& dnsquestion, const std::string&, uint8_t) -> std::vector<std::string> { const auto& data = dnsquestion.getData(); return {Base64Encode(std::string(data.begin(), data.end()))}; }, false},
#ifdef HAVE_DNS_OVER_HTTPS
- ProtoBufMetaKey::KeyTypeDescription{ "doh-header", Type::DoHHeader, [](const DNSQuestion& dq , const std::string& name, uint8_t) -> std::vector<std::string> {
- if (!dq.ids.du) {
- return {};
- }
- auto headers = dq.ids.du->getHTTPHeaders();
- auto it = headers.find(name);
- if (it != headers.end()) {
- return {it->second};
- }
- return {};
- }, true, false },
- ProtoBufMetaKey::KeyTypeDescription{ "doh-host", Type::DoHHost, [](const DNSQuestion& dq, const std::string&, uint8_t) -> std::vector<std::string> {
- if (dq.ids.du) {
- return {dq.ids.du->getHTTPHost()};
- }
- return {};
- }, true, false },
- ProtoBufMetaKey::KeyTypeDescription{ "doh-path", Type::DoHPath, [](const DNSQuestion& dq, const std::string&, uint8_t) -> std::vector<std::string> {
- if (dq.ids.du) {
- return {dq.ids.du->getHTTPPath()};
- }
- return {};
- }, false },
- ProtoBufMetaKey::KeyTypeDescription{ "doh-query-string", Type::DoHQueryString, [](const DNSQuestion& dq, const std::string&, uint8_t) -> std::vector<std::string> {
- if (dq.ids.du) {
- return {dq.ids.du->getHTTPQueryString()};
- }
- return {};
- }, false },
- ProtoBufMetaKey::KeyTypeDescription{ "doh-scheme", Type::DoHScheme, [](const DNSQuestion& dq, const std::string&, uint8_t) -> std::vector<std::string> {
- if (dq.ids.du) {
- return {dq.ids.du->getHTTPScheme()};
- }
- return {};
- }, false, false },
+ ProtoBufMetaKey::KeyTypeDescription{"doh-header", Type::DoHHeader, [](const DNSQuestion& dnsquestion, const std::string& name, uint8_t) -> std::vector<std::string> {
+ if (!dnsquestion.ids.du) {
+ return {};
+ }
+ auto headers = dnsquestion.ids.du->getHTTPHeaders();
+ auto iter = headers.find(name);
+ if (iter != headers.end()) {
+ return {iter->second};
+ }
+ return {};
+ },
+ true, false},
+ ProtoBufMetaKey::KeyTypeDescription{"doh-host", Type::DoHHost, [](const DNSQuestion& dnsquestion, const std::string&, uint8_t) -> std::vector<std::string> {
+ if (dnsquestion.ids.du) {
+ return {dnsquestion.ids.du->getHTTPHost()};
+ }
+ return {};
+ },
+ true, false},
+ ProtoBufMetaKey::KeyTypeDescription{"doh-path", Type::DoHPath, [](const DNSQuestion& dnsquestion, const std::string&, uint8_t) -> std::vector<std::string> {
+ if (dnsquestion.ids.du) {
+ return {dnsquestion.ids.du->getHTTPPath()};
+ }
+ return {};
+ },
+ false},
+ ProtoBufMetaKey::KeyTypeDescription{"doh-query-string", Type::DoHQueryString, [](const DNSQuestion& dnsquestion, const std::string&, uint8_t) -> std::vector<std::string> {
+ if (dnsquestion.ids.du) {
+ return {dnsquestion.ids.du->getHTTPQueryString()};
+ }
+ return {};
+ },
+ false},
+ ProtoBufMetaKey::KeyTypeDescription{"doh-scheme", Type::DoHScheme, [](const DNSQuestion& dnsquestion, const std::string&, uint8_t) -> std::vector<std::string> {
+ if (dnsquestion.ids.du) {
+ return {dnsquestion.ids.du->getHTTPScheme()};
+ }
+ return {};
+ },
+ false, false},
#endif // HAVE_DNS_OVER_HTTPS
- ProtoBufMetaKey::KeyTypeDescription{ "proxy-protocol-value", Type::ProxyProtocolValue, [](const DNSQuestion& dq, const std::string&, uint8_t numericSubKey) -> std::vector<std::string> {
- if (!dq.proxyProtocolValues) {
- return {};
- }
- for (const auto& value : *dq.proxyProtocolValues) {
- if (value.type == numericSubKey) {
- return {value.content};
- }
- }
- return {};
- }, true, false, true },
- ProtoBufMetaKey::KeyTypeDescription{ "proxy-protocol-values", Type::ProxyProtocolValues, [](const DNSQuestion& dq, const std::string&, uint8_t) -> std::vector<std::string> {
- std::vector<std::string> result;
- if (!dq.proxyProtocolValues) {
- return result;
- }
- for (const auto& value : *dq.proxyProtocolValues) {
- result.push_back(std::to_string(value.type) + ":" + value.content);
- }
- return result;
- } },
- ProtoBufMetaKey::KeyTypeDescription{ "tag", Type::Tag, [](const DNSQuestion& dq, const std::string& subKey, uint8_t) -> std::vector<std::string> {
- if (!dq.ids.qTag) {
- return {};
- }
- for (const auto& [key, value] : *dq.ids.qTag) {
- if (key == subKey) {
- return {value};
- }
- }
- return {};
- }, true, true },
- ProtoBufMetaKey::KeyTypeDescription{ "tags", Type::Tags, [](const DNSQuestion& dq, const std::string&, uint8_t) -> std::vector<std::string> {
- std::vector<std::string> result;
- if (!dq.ids.qTag) {
- return result;
- }
- for (const auto& [key, value] : *dq.ids.qTag) {
- if (value.empty()) {
- /* avoids a spurious ':' when the value is empty */
- result.push_back(key);
- }
- else {
- result.push_back(key + ":" + value);
- }
- }
- return result;
- } },
+ ProtoBufMetaKey::KeyTypeDescription{"proxy-protocol-value", Type::ProxyProtocolValue, [](const DNSQuestion& dnsquestion, const std::string&, uint8_t numericSubKey) -> std::vector<std::string> {
+ if (!dnsquestion.proxyProtocolValues) {
+ return {};
+ }
+ for (const auto& value : *dnsquestion.proxyProtocolValues) {
+ if (value.type == numericSubKey) {
+ return {value.content};
+ }
+ }
+ return {};
+ },
+ true, false, true},
+ ProtoBufMetaKey::KeyTypeDescription{"proxy-protocol-values", Type::ProxyProtocolValues, [](const DNSQuestion& dnsquestion, const std::string&, uint8_t) -> std::vector<std::string> {
+ std::vector<std::string> result;
+ if (!dnsquestion.proxyProtocolValues) {
+ return result;
+ }
+ for (const auto& value : *dnsquestion.proxyProtocolValues) {
+ result.push_back(std::to_string(value.type) + ":" + value.content);
+ }
+ return result;
+ }},
+ ProtoBufMetaKey::KeyTypeDescription{"tag", Type::Tag, [](const DNSQuestion& dnsquestion, const std::string& subKey, uint8_t) -> std::vector<std::string> {
+ if (!dnsquestion.ids.qTag) {
+ return {};
+ }
+ for (const auto& [key, value] : *dnsquestion.ids.qTag) {
+ if (key == subKey) {
+ return {value};
+ }
+ }
+ return {};
+ },
+ true, true},
+ ProtoBufMetaKey::KeyTypeDescription{"tags", Type::Tags, [](const DNSQuestion& dnsquestion, const std::string&, uint8_t) -> std::vector<std::string> {
+ std::vector<std::string> result;
+ if (!dnsquestion.ids.qTag) {
+ return result;
+ }
+ for (const auto& [key, value] : *dnsquestion.ids.qTag) {
+ if (value.empty()) {
+ /* avoids a spurious ':' when the value is empty */
+ result.push_back(key);
+ }
+ else {
+ auto tag = key;
+ tag.append(":");
+ tag.append(value);
+ result.push_back(tag);
+ }
+ }
+ return result;
+ }},
};
#endif /* DISABLE_PROTOBUF */