uint32_t cacheKeyNoECS{0}; // 4
// DoH-only */
uint32_t cacheKeyUDP{0}; // 4
+ uint32_t ttlCap{0}; // cap the TTL _after_ inserting into the packet cache // 4
int backendFD{-1}; // 4
int delayMsec{0};
uint16_t qtype{0}; // 2
class ClearRecordTypesResponseAction : public DNSResponseAction, public boost::noncopyable
{
public:
- ClearRecordTypesResponseAction() {}
-
ClearRecordTypesResponseAction(const std::set<QType>& qtypes) : d_qtypes(qtypes)
{
}
};
#endif /* defined(HAVE_LMDB) || defined(HAVE_CDB) */
+class MaxReturnedTTLAction : public DNSAction
+{
+public:
+ MaxReturnedTTLAction(uint32_t cap) : d_cap(cap)
+ {
+ }
+
+ DNSAction::Action operator()(DNSQuestion* dq, std::string* ruleresult) const override
+ {
+ dq->ids.ttlCap = d_cap;
+ return DNSAction::Action::None;
+ }
+
+ std::string toString() const override
+ {
+ return "cap the TTL of the returned response to " + std::to_string(d_cap);
+ }
+
+private:
+ uint32_t d_cap;
+};
+
+class MaxReturnedTTLResponseAction : public DNSResponseAction
+{
+public:
+ MaxReturnedTTLResponseAction(uint32_t cap) : d_cap(cap)
+ {
+ }
+
+ DNSResponseAction::Action operator()(DNSResponse* dr, std::string* ruleresult) const override
+ {
+ dr->ids.ttlCap = d_cap;
+ return DNSResponseAction::Action::None;
+ }
+
+ std::string toString() const override
+ {
+ return "cap the TTL of the returned response to " + std::to_string(d_cap);
+ }
+
+private:
+ uint32_t d_cap;
+};
+
class NegativeAndSOAAction: public DNSAction
{
public:
return std::shared_ptr<DNSResponseAction>(new LimitTTLResponseAction(0, max));
});
+ luaCtx.writeFunction("SetMaxReturnedTTLAction", [](uint32_t max) {
+ return std::shared_ptr<DNSAction>(new MaxReturnedTTLAction(max));
+ });
+
+ luaCtx.writeFunction("SetMaxReturnedTTLResponseAction", [](uint32_t max) {
+ return std::shared_ptr<DNSResponseAction>(new MaxReturnedTTLResponseAction(max));
+ });
+
luaCtx.writeFunction("SetReducedTTLResponseAction", [](uint8_t percentage) {
if (percentage > 100) {
throw std::runtime_error(std::string("SetReducedTTLResponseAction takes a percentage between 0 and 100."));
}
}
+ if (dr.ids.ttlCap > 0) {
+ std::string result;
+ LimitTTLResponseAction ac(0, dr.ids.ttlCap);
+ ac(&dr, &result);
+ }
+
#ifdef HAVE_DNSCRYPT
if (!muted) {
if (!encryptResponse(response, dr.getMaximumSize(), dr.overTCP(), dr.ids.dnsCryptQuery)) {
return false;
}
+ if (dr.ids.ttlCap > 0) {
+ std::string result;
+ LimitTTLResponseAction ac(0, dr.ids.ttlCap);
+ ac(&dr, &result);
+ }
+
#ifdef HAVE_DNSCRYPT
if (!cs.muted) {
if (!encryptResponse(dq.getMutableData(), dq.getMaximumSize(), dq.overTCP(), dq.ids.dnsCryptQuery)) {
// spoof raw response. will just replace qid to match question
void dnsdist_ffi_dnsquestion_spoof_packet(dnsdist_ffi_dnsquestion_t* dq, const char* rawresponse, size_t len) __attribute__ ((visibility ("default")));
+/* 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")));
+
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_set_min_ttl(dnsdist_ffi_dnsresponse_t* dr, uint32_t min) __attribute__ ((visibility ("default")));
void dnsdist_ffi_dnsresponse_set_max_ttl(dnsdist_ffi_dnsresponse_t* dr, uint32_t max) __attribute__ ((visibility ("default")));
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")));
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 {
sa(dq->dq, &result);
}
+void dnsdist_ffi_dnsquestion_set_max_returned_ttl(dnsdist_ffi_dnsquestion_t* dq, uint32_t max)
+{
+ if (dq != nullptr && dq->dq != nullptr) {
+ dq->dq->ids.ttlCap = max;
+ }
+}
+
size_t dnsdist_ffi_servers_list_get_count(const dnsdist_ffi_servers_list_t* list)
{
return list->ffiServers.size();
void dnsdist_ffi_dnsresponse_limit_ttl(dnsdist_ffi_dnsresponse_t* dr, uint32_t min, uint32_t max)
{
- if (dr->dr != nullptr) {
+ if (dr != nullptr && dr->dr != nullptr) {
std::string result;
LimitTTLResponseAction ac(min, max);
ac(dr->dr, &result);
}
}
+void dnsdist_ffi_dnsresponse_set_max_returned_ttl(dnsdist_ffi_dnsresponse_t* dr, uint32_t max)
+{
+ if (dr != nullptr && dr->dr != nullptr) {
+ dr->dr->ids.ttlCap = max;
+ }
+}
+
void dnsdist_ffi_dnsresponse_clear_records_type(dnsdist_ffi_dnsresponse_t* dr, uint16_t qtype)
{
- if (dr->dr != nullptr) {
+ if (dr != nullptr && dr->dr != nullptr) {
clearDNSPacketRecordTypes(dr->dr->getMutableData(), std::set<QType>{qtype});
}
}
- :func:`NoneAction`
- :func:`RemoteLogAction`
- :func:`RemoteLogResponseAction`
+- :func:`SetMaxReturnedTTLResponseAction`
+- :func:`SetMaxReturnedTTLAction`
+- :func:`SetMinTTLResponseAction`
+- :func:`SetMaxTTLResponseAction`
- :func:`SNMPTrapAction`
- :func:`SNMPTrapResponseAction`
- :func:`TeeAction`
:param int option: The EDNS0 option number
+.. function:: SetMaxReturnedTTLAction(max)
+
+ .. versionadded:: 1.8.0
+
+ Cap the TTLs of the response to the given maximum, but only after inserting the response into the packet cache with the initial TTL values.
+
+ :param int max: The maximum allowed value
+
+.. function:: SetMaxReturnedTTLResponseAction(max)
+
+ .. versionadded:: 1.8.0
+
+ Cap the TTLs of the response to the given maximum, but only after inserting the response into the packet cache with the initial TTL values.
+
+ :param int max: The maximum allowed value
+
.. function:: SetMaxTTLResponseAction(max)
.. versionadded:: 1.8.0