::arg().set("remote-connection-string") = "pipe:command=unittest_pipe.py";
::arg().set("remote-dnssec") = "yes";
backendUnderTest = std::move(BackendMakers().all()[0]);
- // load few record types to help out
- SOARecordContent::report();
- NSRecordContent::report();
- ARecordContent::report();
+ reportAllTypes();
}
catch (PDNSException& ex) {
BOOST_TEST_MESSAGE("Cannot start remotebackend: " << ex.reason);
::arg().set("remote-connection-string") = "unix:path=/tmp/remotebackend.sock";
::arg().set("remote-dnssec") = "yes";
backendUnderTest = std::move(BackendMakers().all()[0]);
- // load few record types to help out
- SOARecordContent::report();
- NSRecordContent::report();
- ARecordContent::report();
+ reportAllTypes();
}
catch (PDNSException& ex) {
BOOST_TEST_MESSAGE("Cannot start remotebackend: " << ex.reason);
::arg().set("remote-connection-string") = "zeromq:endpoint=ipc:///tmp/remotebackend.0";
::arg().set("remote-dnssec") = "yes";
backendUnderTest = std::move(BackendMakers().all()[0]);
- // load few record types to help out
- SOARecordContent::report();
- NSRecordContent::report();
- ARecordContent::report();
+ reportAllTypes();
}
catch (PDNSException& ex) {
BOOST_TEST_MESSAGE("Cannot start remotebackend: " << ex.reason);
#include "namespaces.hh"
#include "noinitvector.hh"
-bool DNSRecordContent::d_locked{false};
+std::atomic<bool> DNSRecordContent::d_locked{false};
UnknownRecordContent::UnknownRecordContent(const string& zone)
{
pw.xfrBlob(string(d_record.begin(),d_record.end()));
}
-shared_ptr<DNSRecordContent> DNSRecordContent::deserialize(const DNSName& qname, uint16_t qtype, const string& serialized)
+shared_ptr<DNSRecordContent> DNSRecordContent::deserialize(const DNSName& qname, uint16_t qtype, const string& serialized, uint16_t qclass)
{
dnsheader dnsheader;
memset(&dnsheader, 0, sizeof(dnsheader));
struct dnsrecordheader drh;
drh.d_type=htons(qtype);
- drh.d_class=htons(QClass::IN);
+ drh.d_class=htons(qclass);
drh.d_ttl=0;
drh.d_clen=htons(serialized.size());
}
DNSRecord dr;
- dr.d_class = QClass::IN;
+ dr.d_class = qclass;
dr.d_type = qtype;
dr.d_name = qname;
dr.d_clen = serialized.size();
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#pragma once
+#include <atomic>
#include <map>
#include <sstream>
#include <stdexcept>
}
// parse the content in wire format, possibly including compressed pointers pointing to the owner name
- static shared_ptr<DNSRecordContent> deserialize(const DNSName& qname, uint16_t qtype, const string& serialized);
+ static shared_ptr<DNSRecordContent> deserialize(const DNSName& qname, uint16_t qtype, const string& serialized, uint16_t qclass=QClass::IN);
void doRecordCheck(const struct DNSRecord&){}
static void regist(uint16_t cl, uint16_t ty, makerfunc_t* f, zmakerfunc_t* z, const char* name)
{
- assert(!d_locked); // NOLINT: it's the API
+ assert(!d_locked.load()); // NOLINT: it's the API
if(f)
getTypemap()[pair(cl,ty)]=f;
if(z)
static void lock()
{
- d_locked = true;
+ d_locked.store(true);
}
protected:
static t2namemap_t& getT2Namemap();
static n2typemap_t& getN2Typemap();
static zmakermap_t& getZmakermap();
- static bool d_locked;
+ static std::atomic<bool> d_locked;
};
struct DNSRecord
conv.xfrName(d_fqdn, false);)
/* EUI48 start */
-void EUI48RecordContent::report()
+void EUI48RecordContent::report(const ReportIsOnlyCallableByReportAllTypes& guard)
{
+ (void)guard;
regist(1, QType::EUI48, &make, &make, "EUI48");
}
std::shared_ptr<DNSRecordContent> EUI48RecordContent::make(const DNSRecord &dr, PacketReader& pr)
/* EUI64 start */
-void EUI64RecordContent::report()
+void EUI64RecordContent::report(const ReportIsOnlyCallableByReportAllTypes& guard)
{
+ (void)guard;
regist(1, QType::EUI64, &make, &make, "EUI64");
}
std::shared_ptr<DNSRecordContent> EUI64RecordContent::make(const DNSRecord &dr, PacketReader& pr)
/* APL start */
/* https://tools.ietf.org/html/rfc3123 */
-void APLRecordContent::report()
+void APLRecordContent::report(const ReportIsOnlyCallableByReportAllTypes& guard)
{
+ (void)guard;
regist(1, QType::APL, &make, &make, "APL");
}
return false;
}
-void reportBasicTypes()
+static void reportBasicTypes(const ReportIsOnlyCallableByReportAllTypes& guard)
{
- ARecordContent::report();
- AAAARecordContent::report();
- NSRecordContent::report();
- CNAMERecordContent::report();
- MXRecordContent::report();
- SOARecordContent::report();
- SRVRecordContent::report();
- PTRRecordContent::report();
+ ARecordContent::report(guard);
+ AAAARecordContent::report(guard);
+ NSRecordContent::report(guard);
+ CNAMERecordContent::report(guard);
+ MXRecordContent::report(guard);
+ SOARecordContent::report(guard);
+ SRVRecordContent::report(guard);
+ PTRRecordContent::report(guard);
DNSRecordContent::regist(QClass::CHAOS, QType::TXT, &TXTRecordContent::make, &TXTRecordContent::make, "TXT");
- TXTRecordContent::report();
+ TXTRecordContent::report(guard);
#ifdef HAVE_LUA_RECORDS
- LUARecordContent::report();
+ LUARecordContent::report(guard);
#endif
DNSRecordContent::regist(QClass::IN, QType::ANY, nullptr, nullptr, "ANY");
DNSRecordContent::regist(QClass::IN, QType::AXFR, nullptr, nullptr, "AXFR");
DNSRecordContent::regist(QClass::IN, QType::IXFR, nullptr, nullptr, "IXFR");
}
-void reportOtherTypes()
+static void reportOtherTypes(const ReportIsOnlyCallableByReportAllTypes& guard)
{
- MBRecordContent::report();
- MGRecordContent::report();
- MRRecordContent::report();
- AFSDBRecordContent::report();
- DNAMERecordContent::report();
+ MBRecordContent::report(guard);
+ MGRecordContent::report(guard);
+ MRRecordContent::report(guard);
+ AFSDBRecordContent::report(guard);
+ DNAMERecordContent::report(guard);
#if !defined(RECURSOR)
- ALIASRecordContent::report();
+ ALIASRecordContent::report(guard);
#endif
- SPFRecordContent::report();
- NAPTRRecordContent::report();
- KXRecordContent::report();
- LOCRecordContent::report();
- ENTRecordContent::report();
- HINFORecordContent::report();
- RPRecordContent::report();
- KEYRecordContent::report();
- DNSKEYRecordContent::report();
- DHCIDRecordContent::report();
- CDNSKEYRecordContent::report();
- RKEYRecordContent::report();
- RRSIGRecordContent::report();
- DSRecordContent::report();
- CDSRecordContent::report();
- SSHFPRecordContent::report();
- CERTRecordContent::report();
- NSECRecordContent::report();
- NSEC3RecordContent::report();
- NSEC3PARAMRecordContent::report();
- TLSARecordContent::report();
- SMIMEARecordContent::report();
- OPENPGPKEYRecordContent::report();
- SVCBRecordContent::report();
- HTTPSRecordContent::report();
- DLVRecordContent::report();
+ SPFRecordContent::report(guard);
+ NAPTRRecordContent::report(guard);
+ KXRecordContent::report(guard);
+ LOCRecordContent::report(guard);
+ ENTRecordContent::report(guard);
+ HINFORecordContent::report(guard);
+ RPRecordContent::report(guard);
+ KEYRecordContent::report(guard);
+ DNSKEYRecordContent::report(guard);
+ DHCIDRecordContent::report(guard);
+ CDNSKEYRecordContent::report(guard);
+ RKEYRecordContent::report(guard);
+ RRSIGRecordContent::report(guard);
+ DSRecordContent::report(guard);
+ CDSRecordContent::report(guard);
+ SSHFPRecordContent::report(guard);
+ CERTRecordContent::report(guard);
+ NSECRecordContent::report(guard);
+ NSEC3RecordContent::report(guard);
+ NSEC3PARAMRecordContent::report(guard);
+ TLSARecordContent::report(guard);
+ SMIMEARecordContent::report(guard);
+ OPENPGPKEYRecordContent::report(guard);
+ SVCBRecordContent::report(guard);
+ HTTPSRecordContent::report(guard);
+ DLVRecordContent::report(guard);
DNSRecordContent::regist(QClass::ANY, QType::TSIG, &TSIGRecordContent::make, &TSIGRecordContent::make, "TSIG");
DNSRecordContent::regist(QClass::ANY, QType::TKEY, &TKEYRecordContent::make, &TKEYRecordContent::make, "TKEY");
- //TSIGRecordContent::report();
- OPTRecordContent::report();
- EUI48RecordContent::report();
- EUI64RecordContent::report();
- MINFORecordContent::report();
- URIRecordContent::report();
- CAARecordContent::report();
- APLRecordContent::report();
- IPSECKEYRecordContent::report();
- CSYNCRecordContent::report();
- NIDRecordContent::report();
- L32RecordContent::report();
- L64RecordContent::report();
- LPRecordContent::report();
- ZONEMDRecordContent::report();
+ //TSIGRecordContent::report(guard);
+ OPTRecordContent::report(guard);
+ EUI48RecordContent::report(guard);
+ EUI64RecordContent::report(guard);
+ MINFORecordContent::report(guard);
+ URIRecordContent::report(guard);
+ CAARecordContent::report(guard);
+ APLRecordContent::report(guard);
+ IPSECKEYRecordContent::report(guard);
+ CSYNCRecordContent::report(guard);
+ NIDRecordContent::report(guard);
+ L32RecordContent::report(guard);
+ L64RecordContent::report(guard);
+ LPRecordContent::report(guard);
+ ZONEMDRecordContent::report(guard);
}
+struct ReportIsOnlyCallableByReportAllTypes
+{
+};
+
void reportAllTypes()
{
- reportBasicTypes();
- reportOtherTypes();
+ ReportIsOnlyCallableByReportAllTypes guard;
+ reportBasicTypes(guard);
+ reportOtherTypes(guard);
+ DNSRecordContent::lock();
}
ComboAddress getAddr(const DNSRecord& dr, uint16_t defport)
#include "iputils.hh"
#include "svc-records.hh"
+struct ReportIsOnlyCallableByReportAllTypes;
+
#define includeboilerplate(RNAME) RNAME##RecordContent(const DNSRecord& dr, PacketReader& pr); \
RNAME##RecordContent(const string& zoneData); \
- static void report(void); \
+ static void report(const ReportIsOnlyCallableByReportAllTypes& guard); \
static std::shared_ptr<DNSRecordContent> make(const DNSRecord &dr, PacketReader& pr); \
static std::shared_ptr<DNSRecordContent> make(const string& zonedata); \
string getZoneRepresentation(bool noDot=false) const override; \
class NSECRecordContent : public DNSRecordContent
{
public:
- static void report();
+ static void report(const ReportIsOnlyCallableByReportAllTypes& guard);
NSECRecordContent() = default;
NSECRecordContent(const string& content, const DNSName& zone=DNSName());
class NSEC3RecordContent : public DNSRecordContent
{
public:
- static void report();
+ static void report(const ReportIsOnlyCallableByReportAllTypes& guard);
NSEC3RecordContent() = default;
NSEC3RecordContent(const string& content, const DNSName& zone=DNSName());
class CSYNCRecordContent : public DNSRecordContent
{
public:
- static void report();
+ static void report(const ReportIsOnlyCallableByReportAllTypes& guard);
CSYNCRecordContent() = default;
CSYNCRecordContent(const string& content, const DNSName& zone=DNSName());
class NSEC3PARAMRecordContent : public DNSRecordContent
{
public:
- static void report();
+ static void report(const ReportIsOnlyCallableByReportAllTypes& guard);
NSEC3PARAMRecordContent() = default;
NSEC3PARAMRecordContent(const string& content, const DNSName& zone=DNSName());
class LOCRecordContent : public DNSRecordContent
{
public:
- static void report();
+ static void report(const ReportIsOnlyCallableByReportAllTypes& guard);
LOCRecordContent() = default;
LOCRecordContent(const string& content, const string& zone="");
{
public:
EUI48RecordContent() = default;
- static void report();
+ static void report(const ReportIsOnlyCallableByReportAllTypes& guard);
static std::shared_ptr<DNSRecordContent> make(const DNSRecord &dr, PacketReader& pr);
static std::shared_ptr<DNSRecordContent> make(const string& zone); // FIXME400: DNSName& zone?
string getZoneRepresentation(bool noDot=false) const override;
{
public:
EUI64RecordContent() = default;
- static void report();
+ static void report(const ReportIsOnlyCallableByReportAllTypes& guard);
static std::shared_ptr<DNSRecordContent> make(const DNSRecord &dr, PacketReader& pr);
static std::shared_ptr<DNSRecordContent> make(const string& zone); // FIXME400: DNSName& zone?
string getZoneRepresentation(bool noDot=false) const override;
this->xfrPacket(pw); \
} \
\
-void RNAME##RecordContent::report(void) \
+void RNAME##RecordContent::report(const ReportIsOnlyCallableByReportAllTypes& guard) \
{ \
- regist(1, QType::RNAME, &RNAME##RecordContent::make, &RNAME##RecordContent::make, #RNAME); \
- regist(254, QType::RNAME, &RNAME##RecordContent::make, &RNAME##RecordContent::make, #RNAME); \
+ (void)guard; \
+ regist(1, QType::RNAME, &RNAME##RecordContent::make, &RNAME##RecordContent::make, #RNAME); \
+ regist(254, QType::RNAME, &RNAME##RecordContent::make, &RNAME##RecordContent::make, #RNAME); \
} \
\
RNAME##RecordContent::RNAME##RecordContent(const string& zoneData) \
class MOADNSParser;
bool getEDNSOpts(const MOADNSParser& mdp, EDNSOpts* eo);
-void reportBasicTypes();
-void reportOtherTypes();
void reportAllTypes();
ComboAddress getAddr(const DNSRecord& dr, uint16_t defport=0);
void checkHostnameCorrectness(const DNSResourceRecord& rr);
typedef vector<pair<time_t, LiveCounts> > pcounts_t;
pcounts_t pcounts;
const uint16_t port = g_vm["port"].as<uint16_t>();
- OPTRecordContent::report();
+
+ reportAllTypes();
for(unsigned int fno=0; fno < files.size(); ++fno) {
PcapPacketReader pr(files[fno]);
return ret;
}
-void NSECRecordContent::report()
+void NSECRecordContent::report(const ReportIsOnlyCallableByReportAllTypes& guard)
{
+ (void)guard;
regist(1, 47, &make, &make, "NSEC");
}
////// begin of NSEC3
-void NSEC3RecordContent::report()
+void NSEC3RecordContent::report(const ReportIsOnlyCallableByReportAllTypes& guard)
{
+ (void)guard;
regist(1, 50, &make, &make, "NSEC3");
}
}
-void NSEC3PARAMRecordContent::report()
+void NSEC3PARAMRecordContent::report(const ReportIsOnlyCallableByReportAllTypes& guard)
{
+ (void)guard;
regist(1, 51, &make, &make, "NSEC3PARAM");
regist(254, 51, &make, &make, "NSEC3PARAM");
}
////// begin of CSYNC
-void CSYNCRecordContent::report()
+void CSYNCRecordContent::report(const ReportIsOnlyCallableByReportAllTypes& guard)
{
+ (void)guard;
regist(1, 62, &make, &make, "CSYNC");
}
return (retval);
}
-void LOCRecordContent::report()
+void LOCRecordContent::report(const ReportIsOnlyCallableByReportAllTypes& guard)
{
+ (void)guard;
regist(1, QType::LOC, &make, &make, "LOC");
regist(254, QType::LOC, &make, &make, "LOC");
}
}
BOOST_AUTO_TEST_CASE(test_packetCompress) {
- reportBasicTypes();
vector<unsigned char> packet;
DNSPacketWriter dpw(packet, DNSName("www.ds9a.nl."), QType::AAAA);
dpw.startRecord(DNSName("ds9a.nl"), QType::SOA);
}
BOOST_AUTO_TEST_CASE(test_packetCompressLong) {
- reportBasicTypes();
vector<unsigned char> packet;
DNSName loopback("1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa");
DNSPacketWriter dpw(packet, loopback, QType::PTR);
BOOST_AUTO_TEST_CASE(test_PacketParse) {
vector<unsigned char> packet;
- reportBasicTypes();
DNSName root(".");
DNSPacketWriter dpw1(packet, g_rootdnsname, QType::AAAA);
DNSName p((char*)&packet[0], packet.size(), 12, false);
BOOST_AUTO_TEST_CASE(test_QuestionHash) {
vector<unsigned char> packet(sizeof(dnsheader));
- reportBasicTypes();
bool ok;
// A return init case
BOOST_AUTO_TEST_CASE(test_packetParse) {
vector<unsigned char> packet;
- reportBasicTypes();
DNSPacketWriter dpw(packet, DNSName("www.ds9a.nl."), QType::AAAA);
uint16_t qtype, qclass;
// tuple contains <type, user value, zone representation, line value, broken>
typedef boost::tuple<QType::typeenum, std::string, std::string, std::string, broken_marker> case_t;
typedef std::list<case_t> cases_t;
- MRRecordContent::report();
- IPSECKEYRecordContent::report();
- KXRecordContent::report();
- DHCIDRecordContent::report();
- TSIGRecordContent::report();
- TKEYRecordContent::report();
// NB!!! WHEN ADDING A TEST MAKE SURE YOU PUT IT NEXT TO ITS KIND
// TO MAKE SURE TEST NUMBERING DOES NOT BREAK
BOOST_TEST_MESSAGE("Checking record type " << q.toString() << " test #" << n);
try {
std::string recData;
- auto rec = DNSRecordContent::make(q.getCode(), 1, inval);
- BOOST_CHECK_MESSAGE(rec != NULL, "make( " << q.getCode() << ", 1, " << inval << ") should not return NULL");
+ uint16_t qclass = QClass::IN;
+ if (q.getCode() == QType::TSIG || q.getCode() == QType::TKEY) {
+ qclass = QClass::ANY;
+ }
+ auto rec = DNSRecordContent::make(q.getCode(), qclass, inval);
+ BOOST_CHECK_MESSAGE(rec != nullptr, "make( " << q.getCode() << ", " << qclass << ", " << inval << ") should not return NULL");
if (rec == NULL) continue;
// now verify the record (note that this will be same as *zone* value (except for certain QTypes)
}
recData = rec->serialize(DNSName("rec.test"));
- std::shared_ptr<DNSRecordContent> rec2 = DNSRecordContent::deserialize(DNSName("rec.test"),q.getCode(),recData);
+ auto rec2 = DNSRecordContent::deserialize(DNSName("rec.test"), q.getCode(), recData, qclass);
BOOST_CHECK_MESSAGE(rec2 != NULL, "deserialize(rec.test, " << q.getCode() << ", recData) should not return NULL");
if (rec2 == NULL) continue;
// now verify the zone representation (here it can be different!)
// test that nsid gets parsed into system
std::string packet("\xf0\x01\x01\x00\x00\x01\x00\x01\x00\x00\x00\x01\x03www\x08powerdns\x03""com\x00\x00\x01\x00\x01\x03www\x08powerdns\x03""com\x00\x00\x01\x00\x01\x00\x00\x00\x10\x00\x04\x7f\x00\x00\x01\x00\x00\x29\x05\x00\x00\x00\x00\x00\x00\x0c\x00\x03\x00\x08powerdns",89);
- OPTRecordContent::report();
MOADNSParser mdp(true, (char*)&*packet.begin(), (unsigned int)packet.size());
/* values taken from rfc8080 for ed25519 and ed448, rfc5933 for gost */
DNSName qname(dpk.getAlgorithm() == DNSSECKeeper::ECCGOST ? "www.example.net." : "example.com.");
- reportBasicTypes();
-
RRSIGRecordContent rrc;
uint32_t expire = 1440021600;
uint32_t inception = 1438207200;
BOOST_AUTO_TEST_SUITE(test_zoneparser_tng_cc)
BOOST_AUTO_TEST_CASE(test_tng_record_types) {
- reportAllTypes();
-
std::ostringstream pathbuf;
const char* p = std::getenv("SRCDIR");
if(!p)
}
BOOST_AUTO_TEST_CASE(test_tng_record_generate) {
- reportAllTypes();
-
std::ostringstream pathbuf;
const char* p = std::getenv("SRCDIR");
if(!p)
}
BOOST_AUTO_TEST_CASE(test_tng_upgrade) {
- reportAllTypes();
-
ZoneParserTNG zp(std::vector<std::string>({"foo.test. 86400 IN TYPE1 \\# 4 c0000304"}), DNSName("test"), true);
DNSResourceRecord rr;
zp.get(rr);