InternalQueryState& operator=(const InternalQueryState& orig) = delete;
boost::optional<Netmask> subnet{boost::none}; // 40
+ std::set<QType> ttlCapTypes;
ComboAddress origRemote; // 28
ComboAddress origDest; // 28
ComboAddress hopRemote;
return std::shared_ptr<DNSResponseAction>(new LogResponseAction(fname ? *fname : "", append ? *append : false, buffered ? *buffered : false, verboseOnly ? *verboseOnly : true, includeTimestamp ? *includeTimestamp : false));
});
- luaCtx.writeFunction("LimitTTLResponseAction", [](uint32_t min, uint32_t max) {
- return std::shared_ptr<DNSResponseAction>(new LimitTTLResponseAction(min, max));
+ luaCtx.writeFunction("LimitTTLResponseAction", [](uint32_t min, uint32_t max, boost::optional<LuaArray<uint16_t>> types) {
+ std::set<QType> capTypes;
+ if (types) {
+ for (const auto& [idx, type] : *types) {
+ capTypes.insert(QType(type));
+ }
+ }
+ return std::shared_ptr<DNSResponseAction>(new LimitTTLResponseAction(min, max, capTypes));
});
luaCtx.writeFunction("SetMinTTLResponseAction", [](uint32_t min) {
public:
LimitTTLResponseAction() {}
- LimitTTLResponseAction(uint32_t min, uint32_t max = std::numeric_limits<uint32_t>::max()) : d_min(min), d_max(max)
+ LimitTTLResponseAction(uint32_t min, uint32_t max = std::numeric_limits<uint32_t>::max(), std::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;
std::string toString() const override
{
- return "limit ttl (" + std::to_string(d_min) + " <= ttl <= " + std::to_string(d_max) + ")";
+ 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::set<QType> d_types;
uint32_t d_min{0};
uint32_t d_max{std::numeric_limits<uint32_t>::max()};
};
if (dr.ids.ttlCap > 0) {
std::string result;
- LimitTTLResponseAction ac(0, dr.ids.ttlCap);
+ LimitTTLResponseAction ac(0, dr.ids.ttlCap, dr.ids.ttlCapTypes);
ac(&dr, &result);
}
if (dr.ids.ttlCap > 0) {
std::string result;
- LimitTTLResponseAction ac(0, dr.ids.ttlCap);
+ LimitTTLResponseAction ac(0, dr.ids.ttlCap, dr.ids.ttlCapTypes);
ac(&dr, &result);
}
/* decrease the returned TTL but _after_ inserting the original response into the packet cache */
void dnsdist_ffi_dnsquestion_set_max_returned_ttl(dnsdist_ffi_dnsquestion_t* dq, uint32_t max) __attribute__ ((visibility ("default")));
+/* add a record type to apply the TTL cap to (see above) */
+void dnsdist_ffi_dnsquestion_add_type_to_max_returned_ttl(dnsdist_ffi_dnsquestion_t* dr, uint16_t type) __attribute__ ((visibility ("default")));;
typedef struct dnsdist_ffi_servers_list_t dnsdist_ffi_servers_list_t;
typedef struct dnsdist_ffi_server_t dnsdist_ffi_server_t;
void dnsdist_ffi_dnsresponse_limit_ttl(dnsdist_ffi_dnsresponse_t* dr, uint32_t min, uint32_t max) __attribute__ ((visibility ("default")));
/* decrease the returned TTL but _after_ inserting the original response into the packet cache */
void dnsdist_ffi_dnsresponse_set_max_returned_ttl(dnsdist_ffi_dnsresponse_t* dr, uint32_t max) __attribute__ ((visibility ("default")));
+/* add a record type to apply the TTL cap to (see above) */
+void dnsdist_ffi_dnsresponse_add_type_to_max_returned_ttl(dnsdist_ffi_dnsresponse_t* dr, uint16_t type) __attribute__ ((visibility ("default")));;
void dnsdist_ffi_dnsresponse_clear_records_type(dnsdist_ffi_dnsresponse_t* dr, uint16_t qtype) __attribute__ ((visibility ("default")));
typedef struct dnsdist_ffi_proxy_protocol_value {
}
}
+void dnsdist_ffi_dnsquestion_add_type_to_max_returned_ttl(dnsdist_ffi_dnsquestion_t* dq, uint16_t type)
+{
+ if (dq != nullptr && dq->dq != nullptr) {
+ dq->dq->ids.ttlCapTypes.insert(type);
+ }
+}
+
size_t dnsdist_ffi_servers_list_get_count(const dnsdist_ffi_servers_list_t* list)
{
return list->ffiServers.size();
}
}
+void dnsdist_ffi_dnsresponse_add_type_to_max_returned_ttl(dnsdist_ffi_dnsresponse_t* dr, uint16_t type)
+{
+ if (dr != nullptr && dr->dr != nullptr) {
+ dr->dr->ids.ttlCapTypes.insert(type);
+ }
+}
+
void dnsdist_ffi_dnsresponse_clear_records_type(dnsdist_ffi_dnsresponse_t* dr, uint16_t qtype)
{
if (dr != nullptr && dr->dr != nullptr) {
:param KeyValueLookupKey lookupKey: The key to use for the lookup
:param string destinationTag: The name of the tag to store the result into
-.. function:: LimitTTLResponseAction(min[, max])
+.. function:: LimitTTLResponseAction(min[, max [, types]])
.. versionadded:: 1.8.0
:param int min: The minimum allowed value
:param int max: The maximum allowed value
+ :param list of int: The record types to cap the TTL for. Default is empty which means all records will be capped.
.. function:: LogAction([filename[, binary[, append[, buffered[, verboseOnly[, includeTimestamp]]]]]])