memcpy(packet, &header, sizeof(header));
return true;
}
+
+ void restrictDNSPacketTTLs(PacketBuffer& packet, uint32_t minimumValue, uint32_t maximumValue, const std::unordered_set<QType>& types)
+ {
+ auto visitor = [minimumValue, maximumValue, types](uint8_t section, uint16_t qclass, uint16_t qtype, uint32_t ttl) {
+ if (!types.empty() && qclass == QClass::IN && types.count(qtype) == 0) {
+ return ttl;
+ }
+
+ if (minimumValue > 0) {
+ if (ttl < minimumValue) {
+ ttl = minimumValue;
+ }
+ }
+ if (ttl > maximumValue) {
+ ttl = maximumValue;
+ }
+ return ttl;
+ };
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
+ editDNSPacketTTL(reinterpret_cast<char*>(packet.data()), packet.size(), visitor);
+ }
+
}
void setResponseHeadersFromConfig(dnsheader& dnsheader, const ResponseConfig& config)
{
bool editDNSHeaderFromPacket(PacketBuffer& packet, const std::function<bool(dnsheader& header)>& editFunction);
bool editDNSHeaderFromRawPacket(void* packet, const std::function<bool(dnsheader& header)>& editFunction);
+ void restrictDNSPacketTTLs(PacketBuffer& packet, uint32_t minimumValue, uint32_t maximumValue = std::numeric_limits<uint32_t>::max(), const std::unordered_set<QType>& types = {});
}
struct ResponseConfig
int d_msec;
};
+class LimitTTLResponseAction : public DNSResponseAction, public boost::noncopyable
+{
+public:
+ LimitTTLResponseAction() {}
+
+ LimitTTLResponseAction(uint32_t min, uint32_t max = std::numeric_limits<uint32_t>::max(), const std::unordered_set<QType>& types = {}) :
+ d_types(types), d_min(min), d_max(max)
+ {
+ }
+
+ DNSResponseAction::Action operator()(DNSResponse* dr, std::string* ruleresult) const override
+ {
+ dnsdist::PacketMangling::restrictDNSPacketTTLs(dr->getMutableData(), d_min, d_max, d_types);
+ return DNSResponseAction::Action::None;
+ }
+
+ std::string toString() const override
+ {
+ std::string result = "limit ttl (" + std::to_string(d_min) + " <= ttl <= " + std::to_string(d_max);
+ if (!d_types.empty()) {
+ bool first = true;
+ result += ", types in [";
+ for (const auto& type : d_types) {
+ if (first) {
+ first = false;
+ }
+ else {
+ result += " ";
+ }
+ result += type.toString();
+ }
+ result += "]";
+ }
+ result += +")";
+ return result;
+ }
+
+private:
+ std::unordered_set<QType> d_types;
+ uint32_t d_min{0};
+ uint32_t d_max{std::numeric_limits<uint32_t>::max()};
+};
+
class TeeAction : public DNSAction
{
public:
void dnsdist_ffi_dnsresponse_limit_ttl(dnsdist_ffi_dnsresponse_t* dr, uint32_t min, uint32_t max)
{
if (dr != nullptr && dr->dr != nullptr) {
- std::string result;
- LimitTTLResponseAction ac(min, max);
- ac(dr->dr, &result);
+ dnsdist::PacketMangling::restrictDNSPacketTTLs(dr->dr->getMutableData(), min, max);
}
}
std::optional<uint16_t> d_rawTypeForAny{};
};
-class LimitTTLResponseAction : public DNSResponseAction, public boost::noncopyable
-{
-public:
- LimitTTLResponseAction() {}
-
- LimitTTLResponseAction(uint32_t min, uint32_t max = std::numeric_limits<uint32_t>::max(), const std::unordered_set<QType>& types = {}) :
- d_types(types), d_min(min), d_max(max)
- {
- }
-
- DNSResponseAction::Action operator()(DNSResponse* dr, std::string* ruleresult) const override
- {
- auto visitor = [&](uint8_t section, uint16_t qclass, uint16_t qtype, uint32_t ttl) {
- if (!d_types.empty() && qclass == QClass::IN && d_types.count(qtype) == 0) {
- return ttl;
- }
-
- if (d_min > 0) {
- if (ttl < d_min) {
- ttl = d_min;
- }
- }
- if (ttl > d_max) {
- ttl = d_max;
- }
- return ttl;
- };
- editDNSPacketTTL(reinterpret_cast<char*>(dr->getMutableData().data()), dr->getData().size(), visitor);
- return DNSResponseAction::Action::None;
- }
-
- std::string toString() const override
- {
- std::string result = "limit ttl (" + std::to_string(d_min) + " <= ttl <= " + std::to_string(d_max);
- if (!d_types.empty()) {
- bool first = true;
- result += ", types in [";
- for (const auto& type : d_types) {
- if (first) {
- first = false;
- }
- else {
- result += " ";
- }
- result += type.toString();
- }
- result += "]";
- }
- result += +")";
- return result;
- }
-
-private:
- std::unordered_set<QType> d_types;
- uint32_t d_min{0};
- uint32_t d_max{std::numeric_limits<uint32_t>::max()};
-};
-
template <class T>
using LuaArray = std::vector<std::pair<int, T>>;
template <class T>
}
if (dnsResponse.ids.ttlCap > 0) {
- std::string result;
- LimitTTLResponseAction lrac(0, dnsResponse.ids.ttlCap, {});
- lrac(&dnsResponse, &result);
+ dnsdist::PacketMangling::restrictDNSPacketTTLs(dnsResponse.getMutableData(), 0, dnsResponse.ids.ttlCap);
}
if (dnsResponse.ids.d_extendedError) {
}
if (dnsResponse.ids.ttlCap > 0) {
- std::string result;
- LimitTTLResponseAction ltrac(0, dnsResponse.ids.ttlCap, {});
- ltrac(&dnsResponse, &result);
+ dnsdist::PacketMangling::restrictDNSPacketTTLs(dnsResponse.getMutableData(), 0, dnsResponse.ids.ttlCap);
}
if (dnsResponse.ids.d_extendedError) {