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")));
+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 {
char* value;
void dnsdist_ffi_dnsresponse_limit_ttl(dnsdist_ffi_dnsresponse_t* dr, uint32_t min, uint32_t max)
{
- std::string result;
- LimitTTLResponseAction ac(min, max);
- ac(dr->dr, &result);
+ if (dr->dr != nullptr) {
+ std::string result;
+ LimitTTLResponseAction ac(min, max);
+ ac(dr->dr, &result);
+ }
+}
+
+void dnsdist_ffi_dnsresponse_clear_records_type(dnsdist_ffi_dnsresponse_t* dr, uint16_t qtype)
+{
+ if (dr->dr != nullptr) {
+ clearDNSPacketRecordTypes(dr->dr->getMutableData(), std::set<QType>{qtype});
+ }
}
const std::string& getLuaFFIWrappers()
packet.resize(finalsize);
}
+void clearDNSPacketRecordTypes(PacketBuffer& packet, const std::set<QType>& qtypes)
+{
+ size_t finalsize = packet.size();
+ clearDNSPacketRecordTypes(reinterpret_cast<char*>(packet.data()), finalsize, qtypes);
+ packet.resize(finalsize);
+}
+
// method of operation: silently fail if it doesn't work - we're only trying to be nice, don't fall over on it
void clearDNSPacketRecordTypes(char* packet, size_t& length, const std::set<QType>& qtypes)
{
#include "dns.hh"
#include "dnswriter.hh"
#include "dnsname.hh"
+#include "noinitvector.hh"
#include "pdnsexception.hh"
#include "iputils.hh"
#include "svc-records.hh"
void ageDNSPacket(std::string& packet, uint32_t seconds);
void editDNSPacketTTL(char* packet, size_t length, const std::function<uint32_t(uint8_t, uint16_t, uint16_t, uint32_t)>& visitor);
void clearDNSPacketRecordTypes(vector<uint8_t>& packet, const std::set<QType>& qtypes);
+void clearDNSPacketRecordTypes(PacketBuffer& packet, const std::set<QType>& qtypes);
void clearDNSPacketRecordTypes(char* packet, size_t& length, const std::set<QType>& qtypes);
uint32_t getDNSPacketMinTTL(const char* packet, size_t length, bool* seenAuthSOA=nullptr);
uint32_t getDNSPacketLength(const char* packet, size_t length);
receivedQuery.id = query.id
self.assertEqual(query, receivedQuery)
self.assertEqual(receivedResponse, None)
+
+from pprint import pprint
+
+class TestResponseClearRecordsType(DNSDistTest):
+
+ _config_params = ['_testServerPort']
+ _config_template = """
+ local ffi = require("ffi")
+
+ function luafct(dr)
+ ffi.C.dnsdist_ffi_dnsresponse_clear_records_type(dr, DNSQType.AAAA)
+ return DNSResponseAction.HeaderModify, ""
+ end
+
+ newServer{address="127.0.0.1:%s"}
+
+ addResponseAction("ffi.clear-records-type.responses.tests.powerdns.com.", LuaResponseAction(luafct))
+ """
+
+ def testClearedFFI(self):
+ """
+ Responses: Removes records of a given type (FFI API)
+ """
+ name = 'ffi.clear-records-type.responses.tests.powerdns.com.'
+ query = dns.message.make_query(name, 'A', 'IN')
+ response = dns.message.make_response(query)
+ expectedResponse = dns.message.make_response(query)
+ rrset = dns.rrset.from_text(name,
+ 3600,
+ dns.rdataclass.IN,
+ dns.rdatatype.A,
+ '192.0.2.1')
+ response.answer.append(rrset)
+ expectedResponse.answer.append(rrset)
+ rrset = dns.rrset.from_text(name,
+ 3660,
+ dns.rdataclass.IN,
+ dns.rdatatype.AAAA,
+ '2001:DB8::1', '2001:DB8::2')
+ response.answer.append(rrset)
+ for method in ("sendUDPQuery", "sendTCPQuery"):
+ sender = getattr(self, method)
+ (receivedQuery, receivedResponse) = sender(query, response)
+ receivedQuery.id = query.id
+ self.assertEqual(query, receivedQuery)
+ self.assertEqual(expectedResponse, receivedResponse)