From 32fbb2ab2f7296e33bc778bfe08b14ddfe6f7549 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Tue, 13 Oct 2020 16:27:27 +0200 Subject: [PATCH] Implement a "no-initialization" vector to avoid a perf regression --- pdns/Makefile.am | 1 + pdns/dnscrypt.cc | 18 +- pdns/dnscrypt.hh | 17 +- pdns/dnsdist-cache.cc | 6 +- pdns/dnsdist-cache.hh | 7 +- pdns/dnsdist-dnscrypt.cc | 2 +- pdns/dnsdist-ecs.cc | 42 +-- pdns/dnsdist-ecs.hh | 16 +- pdns/dnsdist-lua-actions.cc | 10 +- pdns/dnsdist-lua-bindings-dnsquestion.cc | 2 +- pdns/dnsdist-lua-bindings.cc | 2 +- pdns/dnsdist-lua-rules.cc | 4 +- pdns/dnsdist.cc | 34 +- pdns/dnsdist.hh | 25 +- pdns/dnsdistdist/Makefile.am | 2 + pdns/dnsdistdist/dnsdist-healthchecks.cc | 4 +- pdns/dnsdistdist/dnsdist-idstate.cc | 2 +- pdns/dnsdistdist/dnsdist-lua-ffi.cc | 2 +- pdns/dnsdistdist/dnsdist-proxy-protocol.cc | 4 +- pdns/dnsdistdist/dnsdist-proxy-protocol.hh | 4 +- pdns/dnsdistdist/dnsdist-secpoll.cc | 2 +- pdns/dnsdistdist/dnsdist-tcp-downstream.cc | 2 +- pdns/dnsdistdist/dnsdist-tcp-downstream.hh | 8 +- pdns/dnsdistdist/dnsdist-tcp-upstream.hh | 2 +- pdns/dnsdistdist/doh.cc | 10 +- pdns/dnsdistdist/noinitvector.hh | 1 + pdns/dnsdistdist/tcpiohandler.cc | 8 +- pdns/dnsdistdist/test-dnsdistkvs_cc.cc | 4 +- pdns/dnsdistdist/test-dnsdistlbpolicies_cc.cc | 4 +- pdns/dnsdistdist/test-dnsdistrules_cc.cc | 2 +- pdns/dnswriter.cc | 48 +-- pdns/dnswriter.hh | 10 +- pdns/doh.hh | 13 +- pdns/fuzz_dnsdistcache.cc | 2 +- pdns/noinitvector.hh | 67 ++++ pdns/recursordist/Makefile.am | 1 + pdns/recursordist/noinitvector.hh | 1 + pdns/sodcrypto.cc | 2 + pdns/tcpiohandler.hh | 9 +- pdns/test-dnscrypt_cc.cc | 30 +- pdns/test-dnsdist_cc.cc | 298 +++++++++--------- pdns/test-dnsdistpacketcache_cc.cc | 82 ++--- 42 files changed, 449 insertions(+), 361 deletions(-) create mode 120000 pdns/dnsdistdist/noinitvector.hh create mode 100644 pdns/noinitvector.hh create mode 120000 pdns/recursordist/noinitvector.hh diff --git a/pdns/Makefile.am b/pdns/Makefile.am index 7050349d954b..5244f412bb0a 100644 --- a/pdns/Makefile.am +++ b/pdns/Makefile.am @@ -224,6 +224,7 @@ pdns_server_SOURCES = \ misc.cc misc.hh \ nameserver.cc nameserver.hh \ namespaces.hh \ + noinitvector.hh \ nsecrecords.cc \ opensslsigners.cc opensslsigners.hh \ packetcache.hh \ diff --git a/pdns/dnscrypt.cc b/pdns/dnscrypt.cc index dca863977f36..4a0abe56569f 100644 --- a/pdns/dnscrypt.cc +++ b/pdns/dnscrypt.cc @@ -384,7 +384,7 @@ void DNSCryptContext::removeInactiveCertificate(uint32_t serial) throw std::runtime_error("No inactive certificate found with this serial"); } -bool DNSCryptQuery::parsePlaintextQuery(const std::vector& packet) +bool DNSCryptQuery::parsePlaintextQuery(const PacketBuffer& packet) { assert(d_ctx != nullptr); @@ -418,9 +418,9 @@ bool DNSCryptQuery::parsePlaintextQuery(const std::vector& packet) return true; } -void DNSCryptContext::getCertificateResponse(time_t now, const DNSName& qname, uint16_t qid, std::vector& response) +void DNSCryptContext::getCertificateResponse(time_t now, const DNSName& qname, uint16_t qid, PacketBuffer& response) { - DNSPacketWriter pw(response, qname, QType::TXT, QClass::IN, Opcode::Query); + GenericDNSPacketWriter pw(response, qname, QType::TXT, QClass::IN, Opcode::Query); struct dnsheader * dh = pw.getHeader(); dh->id = qid; dh->qr = true; @@ -458,7 +458,7 @@ bool DNSCryptContext::magicMatchesAPublicKey(DNSCryptQuery& query, time_t now) return false; } -bool DNSCryptQuery::isEncryptedQuery(const std::vector& packet, bool tcp, time_t now) +bool DNSCryptQuery::isEncryptedQuery(const PacketBuffer& packet, bool tcp, time_t now) { assert(d_ctx != nullptr); @@ -485,7 +485,7 @@ bool DNSCryptQuery::isEncryptedQuery(const std::vector& packet, bool tc return true; } -void DNSCryptQuery::getDecrypted(bool tcp, std::vector& packet) +void DNSCryptQuery::getDecrypted(bool tcp, PacketBuffer& packet) { assert(d_encrypted); assert(d_pair != nullptr); @@ -576,13 +576,13 @@ void DNSCryptQuery::getDecrypted(bool tcp, std::vector& packet) d_valid = true; } -void DNSCryptQuery::getCertificateResponse(time_t now, std::vector& response) const +void DNSCryptQuery::getCertificateResponse(time_t now, PacketBuffer& response) const { assert(d_ctx != nullptr); d_ctx->getCertificateResponse(now, d_qname, d_id, response); } -void DNSCryptQuery::parsePacket(std::vector& packet, bool tcp, time_t now) +void DNSCryptQuery::parsePacket(PacketBuffer& packet, bool tcp, time_t now) { d_valid = false; @@ -635,7 +635,7 @@ uint16_t DNSCryptQuery::computePaddingSize(uint16_t unpaddedLen, size_t maxLen) return result; } -int DNSCryptQuery::encryptResponse(std::vector& response, size_t maxResponseSize, bool tcp) +int DNSCryptQuery::encryptResponse(PacketBuffer& response, size_t maxResponseSize, bool tcp) { struct DNSCryptResponseHeader responseHeader; assert(response.size() > 0); @@ -746,7 +746,7 @@ int DNSCryptQuery::encryptResponse(std::vector& response, size_t maxRes return res; } -int DNSCryptContext::encryptQuery(std::vector& packet, size_t maximumSize, const unsigned char clientPublicKey[DNSCRYPT_PUBLIC_KEY_SIZE], const DNSCryptPrivateKey& clientPrivateKey, const unsigned char clientNonce[DNSCRYPT_NONCE_SIZE / 2], bool tcp, const std::shared_ptr& cert) const +int DNSCryptContext::encryptQuery(PacketBuffer& packet, size_t maximumSize, const unsigned char clientPublicKey[DNSCRYPT_PUBLIC_KEY_SIZE], const DNSCryptPrivateKey& clientPrivateKey, const unsigned char clientNonce[DNSCRYPT_NONCE_SIZE / 2], bool tcp, const std::shared_ptr& cert) const { assert(packet.size() > 0); assert(cert != nullptr); diff --git a/pdns/dnscrypt.hh b/pdns/dnscrypt.hh index 018e90025ad3..a9a579e9c40d 100644 --- a/pdns/dnscrypt.hh +++ b/pdns/dnscrypt.hh @@ -52,6 +52,7 @@ private: #include "dnsname.hh" #include "lock.hh" +#include "noinitvector.hh" #define DNSCRYPT_PROVIDER_PUBLIC_KEY_SIZE (crypto_sign_ed25519_PUBLICKEYBYTES) #define DNSCRYPT_PROVIDER_PRIVATE_KEY_SIZE (crypto_sign_ed25519_SECRETKEYBYTES) @@ -207,10 +208,10 @@ public: d_pair = pair; } - void parsePacket(std::vector& packet, bool tcp, time_t now); - void getDecrypted(bool tcp, std::vector& packet); - void getCertificateResponse(time_t now, std::vector& response) const; - int encryptResponse(std::vector& response, size_t maxResponseSize, bool tcp); + void parsePacket(PacketBuffer& packet, bool tcp, time_t now); + void getDecrypted(bool tcp, PacketBuffer& packet); + void getCertificateResponse(time_t now, PacketBuffer& response) const; + int encryptResponse(PacketBuffer& response, size_t maxResponseSize, bool tcp); static const size_t s_minUDPLength = 256; @@ -221,8 +222,8 @@ private: #endif /* HAVE_CRYPTO_BOX_EASY_AFTERNM */ void fillServerNonce(unsigned char* dest) const; uint16_t computePaddingSize(uint16_t unpaddedLen, size_t maxLen) const; - bool parsePlaintextQuery(const std::vector& packet); - bool isEncryptedQuery(const std::vector& packet, bool tcp, time_t now); + bool parsePlaintextQuery(const PacketBuffer& packet); + bool isEncryptedQuery(const PacketBuffer& packet, bool tcp, time_t now); DNSCryptQueryHeader d_header; #ifdef HAVE_CRYPTO_BOX_EASY_AFTERNM @@ -275,9 +276,9 @@ public: std::vector> getCertificates() { return d_certs; }; const DNSName& getProviderName() const { return providerName; } - int encryptQuery(std::vector& query, size_t maximumSize, const unsigned char clientPublicKey[DNSCRYPT_PUBLIC_KEY_SIZE], const DNSCryptPrivateKey& clientPrivateKey, const unsigned char clientNonce[DNSCRYPT_NONCE_SIZE / 2], bool tcp, const std::shared_ptr& cert) const; + int encryptQuery(PacketBuffer& query, size_t maximumSize, const unsigned char clientPublicKey[DNSCRYPT_PUBLIC_KEY_SIZE], const DNSCryptPrivateKey& clientPrivateKey, const unsigned char clientNonce[DNSCRYPT_NONCE_SIZE / 2], bool tcp, const std::shared_ptr& cert) const; bool magicMatchesAPublicKey(DNSCryptQuery& query, time_t now); - void getCertificateResponse(time_t now, const DNSName& qname, uint16_t qid, std::vector& response); + void getCertificateResponse(time_t now, const DNSName& qname, uint16_t qid, PacketBuffer& response); private: static void computePublicKeyFromPrivate(const DNSCryptPrivateKey& privK, unsigned char pubK[DNSCRYPT_PUBLIC_KEY_SIZE]); diff --git a/pdns/dnsdist-cache.cc b/pdns/dnsdist-cache.cc index f893a0621a75..860322c17ae5 100644 --- a/pdns/dnsdist-cache.cc +++ b/pdns/dnsdist-cache.cc @@ -53,7 +53,7 @@ DNSDistPacketCache::~DNSDistPacketCache() } } -bool DNSDistPacketCache::getClientSubnet(const std::vector& packet, size_t qnameWireLength, boost::optional& subnet) +bool DNSDistPacketCache::getClientSubnet(const PacketBuffer& packet, size_t qnameWireLength, boost::optional& subnet) { uint16_t optRDPosition; size_t remaining = 0; @@ -127,7 +127,7 @@ void DNSDistPacketCache::insertLocked(CacheShard& shard, uint32_t key, CacheValu value = newValue; } -void DNSDistPacketCache::insert(uint32_t key, const boost::optional& subnet, uint16_t queryFlags, bool dnssecOK, const DNSName& qname, uint16_t qtype, uint16_t qclass, const std::vector& response, bool tcp, uint8_t rcode, boost::optional tempFailureTTL) +void DNSDistPacketCache::insert(uint32_t key, const boost::optional& subnet, uint16_t queryFlags, bool dnssecOK, const DNSName& qname, uint16_t qtype, uint16_t qclass, const PacketBuffer& response, bool tcp, uint8_t rcode, boost::optional tempFailureTTL) { if (response.size() < sizeof(dnsheader)) { return; @@ -414,7 +414,7 @@ uint32_t DNSDistPacketCache::getMinTTL(const char* packet, uint16_t length, bool return getDNSPacketMinTTL(packet, length, seenNoDataSOA); } -uint32_t DNSDistPacketCache::getKey(const DNSName::string_t& qname, size_t qnameWireLength, const std::vector& packet, bool tcp) +uint32_t DNSDistPacketCache::getKey(const DNSName::string_t& qname, size_t qnameWireLength, const PacketBuffer& packet, bool tcp) { uint32_t result = 0; /* skip the query ID */ diff --git a/pdns/dnsdist-cache.hh b/pdns/dnsdist-cache.hh index c899a93df542..3b4b14038abb 100644 --- a/pdns/dnsdist-cache.hh +++ b/pdns/dnsdist-cache.hh @@ -26,6 +26,7 @@ #include "iputils.hh" #include "lock.hh" +#include "noinitvector.hh" struct DNSQuestion; @@ -35,7 +36,7 @@ public: DNSDistPacketCache(size_t maxEntries, uint32_t maxTTL=86400, uint32_t minTTL=0, uint32_t tempFailureTTL=60, uint32_t maxNegativeTTL=3600, uint32_t staleTTL=60, bool dontAge=false, uint32_t shards=1, bool deferrableInsertLock=true, bool parseECS=false); ~DNSDistPacketCache(); - void insert(uint32_t key, const boost::optional& subnet, uint16_t queryFlags, bool dnssecOK, const DNSName& qname, uint16_t qtype, uint16_t qclass, const std::vector& response, bool tcp, uint8_t rcode, boost::optional tempFailureTTL); + void insert(uint32_t key, const boost::optional& subnet, uint16_t queryFlags, bool dnssecOK, const DNSName& qname, uint16_t qtype, uint16_t qclass, const PacketBuffer& response, bool tcp, uint8_t rcode, boost::optional tempFailureTTL); bool get(DNSQuestion& dq, uint16_t queryId, uint32_t* keyOut, boost::optional& subnet, bool dnssecOK, uint32_t allowExpired = 0, bool skipAging = false); size_t purgeExpired(size_t upTo=0); size_t expunge(size_t upTo=0); @@ -76,10 +77,10 @@ public: d_parseECS = enabled; } - uint32_t getKey(const DNSName::string_t& qname, size_t qnameWireLength, const std::vector& packet, bool tcp); + uint32_t getKey(const DNSName::string_t& qname, size_t qnameWireLength, const PacketBuffer& packet, bool tcp); static uint32_t getMinTTL(const char* packet, uint16_t length, bool* seenNoDataSOA); - static bool getClientSubnet(const std::vector& packet, size_t qnameWireLength, boost::optional& subnet); + static bool getClientSubnet(const PacketBuffer& packet, size_t qnameWireLength, boost::optional& subnet); private: diff --git a/pdns/dnsdist-dnscrypt.cc b/pdns/dnsdist-dnscrypt.cc index ac254fe9e5b0..fe18169db98b 100644 --- a/pdns/dnsdist-dnscrypt.cc +++ b/pdns/dnsdist-dnscrypt.cc @@ -24,7 +24,7 @@ #include "dnscrypt.hh" #ifdef HAVE_DNSCRYPT -int handleDNSCryptQuery(std::vector& packet, std::shared_ptr& query, bool tcp, time_t now, std::vector& response) +int handleDNSCryptQuery(PacketBuffer& packet, std::shared_ptr& query, bool tcp, time_t now, PacketBuffer& response) { query->parsePacket(packet, tcp, now); diff --git a/pdns/dnsdist-ecs.cc b/pdns/dnsdist-ecs.cc index a45ecd86be2a..fc664da94190 100644 --- a/pdns/dnsdist-ecs.cc +++ b/pdns/dnsdist-ecs.cc @@ -41,7 +41,7 @@ uint16_t g_ECSSourcePrefixV6 = 56; bool g_ECSOverride{false}; bool g_addEDNSToSelfGeneratedResponses{true}; -int rewriteResponseWithoutEDNS(const std::vector& initialPacket, vector& newContent) +int rewriteResponseWithoutEDNS(const PacketBuffer& initialPacket, PacketBuffer& newContent) { assert(initialPacket.size() >= sizeof(dnsheader)); const struct dnsheader* dh = reinterpret_cast(initialPacket.data()); @@ -52,7 +52,7 @@ int rewriteResponseWithoutEDNS(const std::vector& initialPacket, vector if (ntohs(dh->qdcount) == 0) return ENOENT; - GenericPacketReader> pr(initialPacket); + PacketReader pr(pdns_string_view(reinterpret_cast(initialPacket.data()), initialPacket.size())); size_t idx = 0; DNSName rrname; @@ -69,7 +69,7 @@ int rewriteResponseWithoutEDNS(const std::vector& initialPacket, vector rrtype = pr.get16BitInt(); rrclass = pr.get16BitInt(); - DNSPacketWriter pw(newContent, rrname, rrtype, rrclass, dh->opcode); + GenericDNSPacketWriter pw(newContent, rrname, rrtype, rrclass, dh->opcode); pw.getHeader()->id=dh->id; pw.getHeader()->qr=dh->qr; pw.getHeader()->aa=dh->aa; @@ -149,7 +149,7 @@ static bool addOrReplaceECSOption(std::vector>& return true; } -static bool slowRewriteQueryWithExistingEDNS(const std::vector& initialPacket, vector& newContent, bool& ednsAdded, bool& ecsAdded, bool overrideExisting, const string& newECSOption) +static bool slowRewriteQueryWithExistingEDNS(const PacketBuffer& initialPacket, PacketBuffer& newContent, bool& ednsAdded, bool& ecsAdded, bool overrideExisting, const string& newECSOption) { assert(initialPacket.size() >= sizeof(dnsheader)); const struct dnsheader* dh = reinterpret_cast(initialPacket.data()); @@ -165,7 +165,7 @@ static bool slowRewriteQueryWithExistingEDNS(const std::vector& initial throw std::runtime_error("slowRewriteQueryWithExistingEDNS() should not be called for queries that have no EDNS"); } - GenericPacketReader> pr(initialPacket); + PacketReader pr(pdns_string_view(reinterpret_cast(initialPacket.data()), initialPacket.size())); size_t idx = 0; DNSName rrname; @@ -182,7 +182,7 @@ static bool slowRewriteQueryWithExistingEDNS(const std::vector& initial rrtype = pr.get16BitInt(); rrclass = pr.get16BitInt(); - DNSPacketWriter pw(newContent, rrname, rrtype, rrclass, dh->opcode); + GenericDNSPacketWriter pw(newContent, rrname, rrtype, rrclass, dh->opcode); pw.getHeader()->id=dh->id; pw.getHeader()->qr=dh->qr; pw.getHeader()->aa=dh->aa; @@ -261,7 +261,7 @@ static bool slowRewriteQueryWithExistingEDNS(const std::vector& initial return true; } -static bool slowParseEDNSOptions(const std::vector& packet, std::shared_ptr >& options) +static bool slowParseEDNSOptions(const PacketBuffer& packet, std::shared_ptr >& options) { if (packet.size() < sizeof(dnsheader)) { return false; @@ -317,7 +317,7 @@ static bool slowParseEDNSOptions(const std::vector& packet, std::shared return true; } -int locateEDNSOptRR(const std::vector& packet, uint16_t * optStart, size_t * optLen, bool * last) +int locateEDNSOptRR(const PacketBuffer& packet, uint16_t * optStart, size_t * optLen, bool * last) { assert(optStart != NULL); assert(optLen != NULL); @@ -327,7 +327,7 @@ int locateEDNSOptRR(const std::vector& packet, uint16_t * optStart, siz if (ntohs(dh->arcount) == 0) return ENOENT; - GenericPacketReader> pr(packet); + PacketReader pr(pdns_string_view(reinterpret_cast(packet.data()), packet.size())); size_t idx = 0; DNSName rrname; @@ -384,7 +384,7 @@ int locateEDNSOptRR(const std::vector& packet, uint16_t * optStart, siz } /* extract the start of the OPT RR in a QUERY packet if any */ -int getEDNSOptionsStart(const std::vector& packet, const size_t offset, uint16_t* optRDPosition, size_t* remaining) +int getEDNSOptionsStart(const PacketBuffer& packet, const size_t offset, uint16_t* optRDPosition, size_t* remaining) { assert(optRDPosition != nullptr); assert(remaining != nullptr); @@ -437,7 +437,7 @@ void generateECSOption(const ComboAddress& source, string& res, uint16_t ECSPref generateEDNSOption(EDNSOptionCode::ECS, payload, res); } -bool generateOptRR(const std::string& optRData, std::vector& res, size_t maximumSize, uint16_t udpPayloadSize, uint8_t ednsrcode, bool dnssecOK) +bool generateOptRR(const std::string& optRData, PacketBuffer& res, size_t maximumSize, uint16_t udpPayloadSize, uint8_t ednsrcode, bool dnssecOK) { const uint8_t name = 0; dnsrecordheader dh; @@ -464,7 +464,7 @@ bool generateOptRR(const std::string& optRData, std::vector& res, size_ return true; } -static bool replaceEDNSClientSubnetOption(std::vector& packet, size_t maximumSize, size_t const oldEcsOptionStartPosition, size_t const oldEcsOptionSize, size_t const optRDLenPosition, const string& newECSOption) +static bool replaceEDNSClientSubnetOption(PacketBuffer& packet, size_t maximumSize, size_t const oldEcsOptionStartPosition, size_t const oldEcsOptionSize, size_t const optRDLenPosition, const string& newECSOption) { assert(oldEcsOptionStartPosition < packet.size()); assert(optRDLenPosition < packet.size()); @@ -536,7 +536,7 @@ bool parseEDNSOptions(const DNSQuestion& dq) return false; } -static bool addECSToExistingOPT(std::vector& packet, size_t maximumSize, const string& newECSOption, size_t optRDLenPosition, bool& ecsAdded) +static bool addECSToExistingOPT(PacketBuffer& packet, size_t maximumSize, const string& newECSOption, size_t optRDLenPosition, bool& ecsAdded) { /* we need to add one EDNS0 ECS option, fixing the size of EDNS0 RDLENGTH */ /* getEDNSOptionsStart has already checked that there is exactly one AR, @@ -562,7 +562,7 @@ static bool addECSToExistingOPT(std::vector& packet, size_t maximumSize return true; } -static bool addEDNSWithECS(std::vector& packet, size_t maximumSize, const string& newECSOption, bool& ednsAdded, bool& ecsAdded) +static bool addEDNSWithECS(PacketBuffer& packet, size_t maximumSize, const string& newECSOption, bool& ednsAdded, bool& ecsAdded) { if (!generateOptRR(newECSOption, packet, maximumSize, g_EdnsUDPPayloadSize, 0, false)) { return false; @@ -578,14 +578,14 @@ static bool addEDNSWithECS(std::vector& packet, size_t maximumSize, con return true; } -bool handleEDNSClientSubnet(std::vector& packet, const size_t maximumSize, const size_t qnameWireLength, bool& ednsAdded, bool& ecsAdded, bool overrideExisting, const string& newECSOption) +bool handleEDNSClientSubnet(PacketBuffer& packet, const size_t maximumSize, const size_t qnameWireLength, bool& ednsAdded, bool& ecsAdded, bool overrideExisting, const string& newECSOption) { assert(qnameWireLength <= packet.size()); const struct dnsheader* dh = reinterpret_cast(packet.data()); if (ntohs(dh->ancount) != 0 || ntohs(dh->nscount) != 0 || (ntohs(dh->arcount) != 0 && ntohs(dh->arcount) != 1)) { - vector newContent; + PacketBuffer newContent; newContent.reserve(packet.size()); if (!slowRewriteQueryWithExistingEDNS(packet, newContent, ednsAdded, ecsAdded, overrideExisting, newECSOption)) { @@ -709,7 +709,7 @@ int removeEDNSOptionFromOPT(char* optStart, size_t* optLen, const uint16_t optio return 0; } -bool isEDNSOptionInOpt(const std::vector& packet, const size_t optStart, const size_t optLen, const uint16_t optionCodeToFind, size_t* optContentStart, uint16_t* optContentLen) +bool isEDNSOptionInOpt(const PacketBuffer& packet, const size_t optStart, const size_t optLen, const uint16_t optionCodeToFind, size_t* optContentStart, uint16_t* optContentLen) { if (optLen < optRecordMinimumSize) { return false; @@ -748,7 +748,7 @@ bool isEDNSOptionInOpt(const std::vector& packet, const size_t optStart return false; } -int rewriteResponseWithoutEDNSOption(const std::vector& initialPacket, const uint16_t optionCodeToSkip, vector& newContent) +int rewriteResponseWithoutEDNSOption(const PacketBuffer& initialPacket, const uint16_t optionCodeToSkip, PacketBuffer& newContent) { assert(initialPacket.size() >= sizeof(dnsheader)); const struct dnsheader* dh = reinterpret_cast(initialPacket.data()); @@ -759,7 +759,7 @@ int rewriteResponseWithoutEDNSOption(const std::vector& initialPacket, if (ntohs(dh->qdcount) == 0) return ENOENT; - GenericPacketReader> pr(initialPacket); + PacketReader pr(pdns_string_view(reinterpret_cast(initialPacket.data()), initialPacket.size())); size_t idx = 0; DNSName rrname; @@ -776,7 +776,7 @@ int rewriteResponseWithoutEDNSOption(const std::vector& initialPacket, rrtype = pr.get16BitInt(); rrclass = pr.get16BitInt(); - DNSPacketWriter pw(newContent, rrname, rrtype, rrclass, dh->opcode); + GenericDNSPacketWriter pw(newContent, rrname, rrtype, rrclass, dh->opcode); pw.getHeader()->id=dh->id; pw.getHeader()->qr=dh->qr; pw.getHeader()->aa=dh->aa; @@ -845,7 +845,7 @@ int rewriteResponseWithoutEDNSOption(const std::vector& initialPacket, return 0; } -bool addEDNS(std::vector& packet, size_t maximumSize, bool dnssecOK, uint16_t payloadSize, uint8_t ednsrcode) +bool addEDNS(PacketBuffer& packet, size_t maximumSize, bool dnssecOK, uint16_t payloadSize, uint8_t ednsrcode) { if (!generateOptRR(std::string(), packet, maximumSize, payloadSize, ednsrcode, dnssecOK)) { return false; diff --git a/pdns/dnsdist-ecs.hh b/pdns/dnsdist-ecs.hh index 60492576958c..26f758b6dbbd 100644 --- a/pdns/dnsdist-ecs.hh +++ b/pdns/dnsdist-ecs.hh @@ -27,20 +27,20 @@ static const size_t optRecordMinimumSize = 11; extern size_t g_EdnsUDPPayloadSize; extern uint16_t g_PayloadSizeSelfGenAnswers; -int rewriteResponseWithoutEDNS(const std::vector& initialPacket, vector& newContent); -int locateEDNSOptRR(const std::vector & packet, uint16_t * optStart, size_t * optLen, bool * last); -bool generateOptRR(const std::string& optRData, std::vector& res, size_t maximumSize, uint16_t udpPayloadSize, uint8_t ednsrcode, bool dnssecOK); +int rewriteResponseWithoutEDNS(const PacketBuffer& initialPacket, PacketBuffer& newContent); +int locateEDNSOptRR(const PacketBuffer & packet, uint16_t * optStart, size_t * optLen, bool * last); +bool generateOptRR(const std::string& optRData, PacketBuffer& res, size_t maximumSize, uint16_t udpPayloadSize, uint8_t ednsrcode, bool dnssecOK); void generateECSOption(const ComboAddress& source, string& res, uint16_t ECSPrefixLength); int removeEDNSOptionFromOPT(char* optStart, size_t* optLen, const uint16_t optionCodeToRemove); -int rewriteResponseWithoutEDNSOption(const std::vector& initialPacket, const uint16_t optionCodeToSkip, vector& newContent); -int getEDNSOptionsStart(const std::vector& packet, const size_t offset, uint16_t* optRDPosition, size_t * remaining); -bool isEDNSOptionInOpt(const std::vector& packet, const size_t optStart, const size_t optLen, const uint16_t optionCodeToFind, size_t* optContentStart = nullptr, uint16_t* optContentLen = nullptr); -bool addEDNS(std::vector& packet, size_t maximumSize, bool dnssecOK, uint16_t payloadSize, uint8_t ednsrcode); +int rewriteResponseWithoutEDNSOption(const PacketBuffer& initialPacket, const uint16_t optionCodeToSkip, PacketBuffer& newContent); +int getEDNSOptionsStart(const PacketBuffer& packet, const size_t offset, uint16_t* optRDPosition, size_t * remaining); +bool isEDNSOptionInOpt(const PacketBuffer& packet, const size_t optStart, const size_t optLen, const uint16_t optionCodeToFind, size_t* optContentStart = nullptr, uint16_t* optContentLen = nullptr); +bool addEDNS(PacketBuffer& packet, size_t maximumSize, bool dnssecOK, uint16_t payloadSize, uint8_t ednsrcode); bool addEDNSToQueryTurnedResponse(DNSQuestion& dq); bool setNegativeAndAdditionalSOA(DNSQuestion& dq, bool nxd, const DNSName& zone, uint32_t ttl, const DNSName& mname, const DNSName& rname, uint32_t serial, uint32_t refresh, uint32_t retry, uint32_t expire, uint32_t minimum); bool handleEDNSClientSubnet(DNSQuestion& dq, bool& ednsAdded, bool& ecsAdded); -bool handleEDNSClientSubnet(std::vector& packet, size_t maximumSize, size_t qnameWireLength, bool& ednsAdded, bool& ecsAdded, bool overrideExisting, const string& newECSOption); +bool handleEDNSClientSubnet(PacketBuffer& packet, size_t maximumSize, size_t qnameWireLength, bool& ednsAdded, bool& ecsAdded, bool overrideExisting, const string& newECSOption); bool parseEDNSOptions(const DNSQuestion& dq); diff --git a/pdns/dnsdist-lua-actions.cc b/pdns/dnsdist-lua-actions.cc index 0a3d7abaa9bb..4a234bf1aa59 100644 --- a/pdns/dnsdist-lua-actions.cc +++ b/pdns/dnsdist-lua-actions.cc @@ -174,7 +174,7 @@ DNSAction::Action TeeAction::operator()(DNSQuestion* dq, std::string* ruleresult d_queries++; if(d_addECS) { - std::vector query(dq->getData()); + PacketBuffer query(dq->getData()); bool ednsAdded = false; bool ecsAdded = false; @@ -1309,7 +1309,7 @@ class ContinueAction : public DNSAction class HTTPStatusAction: public DNSAction { public: - HTTPStatusAction(int code, const std::vector& body, const std::string& contentType): d_body(body), d_contentType(contentType), d_code(code) + HTTPStatusAction(int code, const PacketBuffer& body, const std::string& contentType): d_body(body), d_contentType(contentType), d_code(code) { } @@ -1319,7 +1319,7 @@ class HTTPStatusAction: public DNSAction return Action::None; } - dq->du->setHTTPResponse(d_code, std::vector(d_body), d_contentType); + dq->du->setHTTPResponse(d_code, PacketBuffer(d_body), d_contentType); dq->getHeader()->qr = true; // for good measure setResponseHeadersFromConfig(*dq->getHeader(), d_responseConfig); return Action::HeaderModify; @@ -1332,7 +1332,7 @@ class HTTPStatusAction: public DNSAction ResponseConfig d_responseConfig; private: - std::vector d_body; + PacketBuffer d_body; std::string d_contentType; int d_code; }; @@ -1811,7 +1811,7 @@ void setupLuaActions(LuaContext& luaCtx) #ifdef HAVE_DNS_OVER_HTTPS luaCtx.writeFunction("HTTPStatusAction", [](uint16_t status, std::string body, boost::optional contentType, boost::optional vars) { - auto ret = std::shared_ptr(new HTTPStatusAction(status, std::vector(body.begin(), body.end()), contentType ? *contentType : "")); + auto ret = std::shared_ptr(new HTTPStatusAction(status, PacketBuffer(body.begin(), body.end()), contentType ? *contentType : "")); auto hsa = std::dynamic_pointer_cast(ret); parseResponseConfig(vars, hsa->d_responseConfig); return ret; diff --git a/pdns/dnsdist-lua-bindings-dnsquestion.cc b/pdns/dnsdist-lua-bindings-dnsquestion.cc index 553b1f521762..34f52accb81e 100644 --- a/pdns/dnsdist-lua-bindings-dnsquestion.cc +++ b/pdns/dnsdist-lua-bindings-dnsquestion.cc @@ -236,7 +236,7 @@ void setupLuaBindingsDNSQuestion(LuaContext& luaCtx) if (dq.du == nullptr) { return; } - std::vector vect(body.begin(), body.end()); + PacketBuffer vect(body.begin(), body.end()); dq.du->setHTTPResponse(statusCode, std::move(vect), contentType ? *contentType : ""); }); #endif /* HAVE_DNS_OVER_HTTPS */ diff --git a/pdns/dnsdist-lua-bindings.cc b/pdns/dnsdist-lua-bindings.cc index d7a8b6abfe61..8be20c596503 100644 --- a/pdns/dnsdist-lua-bindings.cc +++ b/pdns/dnsdist-lua-bindings.cc @@ -490,6 +490,6 @@ void setupLuaBindings(LuaContext& luaCtx, bool client) headers->push_back({ boost::to_lower_copy(header.first), header.second }); } } - return std::make_shared(regex, status, std::vector(content.begin(), content.end()), headers); + return std::make_shared(regex, status, PacketBuffer(content.begin(), content.end()), headers); }); } diff --git a/pdns/dnsdist-lua-rules.cc b/pdns/dnsdist-lua-rules.cc index 0ad71bd8e556..68dee6bf96f6 100644 --- a/pdns/dnsdist-lua-rules.cc +++ b/pdns/dnsdist-lua-rules.cc @@ -419,7 +419,7 @@ void setupLuaRules(LuaContext& luaCtx) int times = times_.get_value_or(100000); DNSName suffix(suffix_.get_value_or("powerdns.com")); struct item { - vector packet; + PacketBuffer packet; ComboAddress rem; DNSName qname; uint16_t qtype, qclass; @@ -434,7 +434,7 @@ void setupLuaRules(LuaContext& luaCtx) i.qclass = 1; i.rem=ComboAddress("127.0.0.1"); i.rem.sin4.sin_addr.s_addr = random(); - DNSPacketWriter pw(i.packet, i.qname, i.qtype); + GenericDNSPacketWriter pw(i.packet, i.qname, i.qtype); items.push_back(i); } diff --git a/pdns/dnsdist.cc b/pdns/dnsdist.cc index a64483c8d2f1..09585afc22bc 100644 --- a/pdns/dnsdist.cc +++ b/pdns/dnsdist.cc @@ -147,7 +147,7 @@ std::set g_capabilitiesToRetain; static size_t const s_initialUDPPacketBufferSize = s_maxPacketCacheEntrySize + DNSCRYPT_MAX_RESPONSE_PADDING_AND_MAC_SIZE; static_assert(s_initialUDPPacketBufferSize <= UINT16_MAX, "Packet size should fit in a uint16_t"); -static void truncateTC(std::vector& packet, size_t maximumSize, unsigned int qnameWireLength) +static void truncateTC(PacketBuffer& packet, size_t maximumSize, unsigned int qnameWireLength) { try { @@ -176,7 +176,7 @@ static void truncateTC(std::vector& packet, size_t maximumSize, unsigne struct DelayedPacket { int fd; - std::vector packet; + PacketBuffer packet; ComboAddress destination; ComboAddress origDest; void operator()() @@ -235,7 +235,7 @@ void doLatencyStats(double udiff) doAvg(g_stats.latencyAvg1000000, udiff, 1000000); } -bool responseContentMatches(const std::vector& response, const DNSName& qname, const uint16_t qtype, const uint16_t qclass, const ComboAddress& remote, unsigned int& qnameWireLength) +bool responseContentMatches(const PacketBuffer& response, const DNSName& qname, const uint16_t qtype, const uint16_t qclass, const ComboAddress& remote, unsigned int& qnameWireLength) { if (response.size() < sizeof(dnsheader)) { return false; @@ -298,7 +298,7 @@ static bool fixUpQueryTurnedResponse(DNSQuestion& dq, const uint16_t origFlags) return addEDNSToQueryTurnedResponse(dq); } -static bool fixUpResponse(std::vector& response, const DNSName& qname, uint16_t origFlags, bool ednsAdded, bool ecsAdded, bool* zeroScope) +static bool fixUpResponse(PacketBuffer& response, const DNSName& qname, uint16_t origFlags, bool ednsAdded, bool ecsAdded, bool* zeroScope) { if (response.size() < sizeof(dnsheader)) { return false; @@ -350,7 +350,7 @@ static bool fixUpResponse(std::vector& response, const DNSName& qname, } else { /* Removing an intermediary RR could lead to compression error */ - std::vector rewrittenResponse; + PacketBuffer rewrittenResponse; if (rewriteResponseWithoutEDNS(response, rewrittenResponse) == 0) { response = std::move(rewrittenResponse); } @@ -370,7 +370,7 @@ static bool fixUpResponse(std::vector& response, const DNSName& qname, response.resize(response.size() - (existingOptLen - optLen)); } else { - std::vector rewrittenResponse; + PacketBuffer rewrittenResponse; /* Removing an intermediary RR could lead to compression error */ if (rewriteResponseWithoutEDNSOption(response, EDNSOptionCode::ECS, rewrittenResponse) == 0) { response = std::move(rewrittenResponse); @@ -387,7 +387,7 @@ static bool fixUpResponse(std::vector& response, const DNSName& qname, } #ifdef HAVE_DNSCRYPT -static bool encryptResponse(std::vector& response, size_t maximumSize, bool tcp, std::shared_ptr dnsCryptQuery) +static bool encryptResponse(PacketBuffer& response, size_t maximumSize, bool tcp, std::shared_ptr dnsCryptQuery) { if (dnsCryptQuery) { int res = dnsCryptQuery->encryptResponse(response, maximumSize, tcp); @@ -436,7 +436,7 @@ static bool applyRulesToResponse(LocalStateHolder& response, LocalStateHolder >& localRespRulactions, DNSResponse& dr, bool muted) +bool processResponse(PacketBuffer& response, LocalStateHolder >& localRespRulactions, DNSResponse& dr, bool muted) { if (!applyRulesToResponse(localRespRulactions, dr)) { return false; @@ -474,7 +474,7 @@ bool processResponse(std::vector& response, LocalStateHolder& response, const int delayMsec, const ComboAddress& origDest, const ComboAddress& origRemote) +static bool sendUDPResponse(int origFD, const PacketBuffer& response, const int delayMsec, const ComboAddress& origDest, const ComboAddress& origRemote) { if(delayMsec && g_delay) { DelayedPacket dp{origFD, response, origRemote, origDest}; @@ -524,7 +524,7 @@ void responderThread(std::shared_ptr dss) try { setThreadName("dnsdist/respond"); auto localRespRulactions = g_resprulactions.getLocal(); - std::vector response(s_initialUDPPacketBufferSize); + PacketBuffer response(s_initialUDPPacketBufferSize); /* when the answer is encrypted in place, we need to get a copy of the original header before encryption to fill the ring buffer */ @@ -976,7 +976,7 @@ static bool applyRulesToQuery(LocalHolders& holders, DNSQuestion& dq, const stru return true; } -ssize_t udpClientSendRequestToBackend(const std::shared_ptr& ss, const int sd, const std::vector& request, bool healthCheck) +ssize_t udpClientSendRequestToBackend(const std::shared_ptr& ss, const int sd, const PacketBuffer& request, bool healthCheck) { ssize_t result; @@ -1039,11 +1039,11 @@ static bool isUDPQueryAcceptable(ClientState& cs, LocalHolders& holders, const s return true; } -bool checkDNSCryptQuery(const ClientState& cs, std::vector& query, std::shared_ptr& dnsCryptQuery, time_t now, bool tcp) +bool checkDNSCryptQuery(const ClientState& cs, PacketBuffer& query, std::shared_ptr& dnsCryptQuery, time_t now, bool tcp) { if (cs.dnscryptCtx) { #ifdef HAVE_DNSCRYPT - vector response; + PacketBuffer response; dnsCryptQuery = std::make_shared(cs.dnscryptCtx); bool decrypted = handleDNSCryptQuery(query, dnsCryptQuery, tcp, now, response); @@ -1080,7 +1080,7 @@ bool checkQueryHeaders(const struct dnsheader* dh) } #if defined(HAVE_RECVMMSG) && defined(HAVE_SENDMMSG) && defined(MSG_WAITFORONE) -static void queueResponse(const ClientState& cs, const std::vector& response, const ComboAddress& dest, const ComboAddress& remote, struct mmsghdr& outMsg, struct iovec* iov, cmsgbuf_aligned* cbuf) +static void queueResponse(const ClientState& cs, const PacketBuffer& response, const ComboAddress& dest, const ComboAddress& remote, struct mmsghdr& outMsg, struct iovec* iov, cmsgbuf_aligned* cbuf) { outMsg.msg_len = 0; fillMSGHdr(&outMsg.msg_hdr, iov, nullptr, 0, const_cast(reinterpret_cast(&response.at(0))), response.size(), const_cast(&remote)); @@ -1249,7 +1249,7 @@ ProcessQueryResult processQuery(DNSQuestion& dq, ClientState& cs, LocalHolders& return ProcessQueryResult::Drop; } -static void processUDPQuery(ClientState& cs, LocalHolders& holders, const struct msghdr* msgh, const ComboAddress& remote, ComboAddress& dest, std::vector& query, struct mmsghdr* responsesVect, unsigned int* queuedResponses, struct iovec* respIOV, cmsgbuf_aligned* respCBuf) +static void processUDPQuery(ClientState& cs, LocalHolders& holders, const struct msghdr* msgh, const ComboAddress& remote, ComboAddress& dest, PacketBuffer& query, struct mmsghdr* responsesVect, unsigned int* queuedResponses, struct iovec* respIOV, cmsgbuf_aligned* respCBuf) { assert(responsesVect == nullptr || (queuedResponses != nullptr && respIOV != nullptr && respCBuf != nullptr)); uint16_t queryId = 0; @@ -1385,7 +1385,7 @@ static void MultipleMessagesUDPClientThread(ClientState* cs, LocalHolders& holde { struct MMReceiver { - std::vector packet; + PacketBuffer packet; ComboAddress remote; ComboAddress dest; struct iovec iov; @@ -1478,7 +1478,7 @@ try else #endif /* defined(HAVE_RECVMMSG) && defined(HAVE_SENDMMSG) && defined(MSG_WAITFORONE) */ { - std::vector packet(s_initialUDPPacketBufferSize); + PacketBuffer packet(s_initialUDPPacketBufferSize); /* the actual buffer is larger because: - we may have to add EDNS and/or ECS - we use it for self-generated responses (from rule or cache) diff --git a/pdns/dnsdist.hh b/pdns/dnsdist.hh index 7ab0be192b1d..bd9387dc131d 100644 --- a/pdns/dnsdist.hh +++ b/pdns/dnsdist.hh @@ -46,6 +46,7 @@ #include "iputils.hh" #include "misc.hh" #include "mplexer.hh" +#include "noinitvector.hh" #include "sholder.hh" #include "tcpiohandler.hh" #include "uuid-utils.hh" @@ -58,11 +59,11 @@ extern uint16_t g_ECSSourcePrefixV4; extern uint16_t g_ECSSourcePrefixV6; extern bool g_ECSOverride; -typedef std::unordered_map QTag; +using QTag = std::unordered_map; struct DNSQuestion { - DNSQuestion(const DNSName* name, uint16_t type, uint16_t class_, const ComboAddress* lc, const ComboAddress* rem, std::vector& data_, bool isTcp, const struct timespec* queryTime_): + DNSQuestion(const DNSName* name, uint16_t type, uint16_t class_, const ComboAddress* lc, const ComboAddress* rem, PacketBuffer& data_, bool isTcp, const struct timespec* queryTime_): data(data_), qname(name), local(lc), remote(rem), queryTime(queryTime_), tempFailureTTL(boost::none), qtype(type), qclass(class_), ecsPrefixLength(rem->sin4.sin_family == AF_INET ? g_ECSSourcePrefixV4 : g_ECSSourcePrefixV6), tcp(isTcp), ecsOverride(g_ECSOverride) { const uint16_t* flags = getFlagsFromDNSHeader(getHeader()); origFlags = *flags; @@ -73,11 +74,11 @@ struct DNSQuestion std::string getTrailingData() const; bool setTrailingData(const std::string&); - const std::vector& getData() const + const PacketBuffer& getData() const { return data; } - std::vector& getMutableData() + PacketBuffer& getMutableData() { return data; } @@ -112,7 +113,7 @@ struct DNSQuestion } protected: - std::vector& data; + PacketBuffer& data; public: boost::optional uniqueId; @@ -153,7 +154,7 @@ public: struct DNSResponse : DNSQuestion { - DNSResponse(const DNSName* name, uint16_t type, uint16_t class_, const ComboAddress* lc, const ComboAddress* rem, std::vector& data_, bool isTcp, const struct timespec* queryTime_): + DNSResponse(const DNSName* name, uint16_t type, uint16_t class_, const ComboAddress* lc, const ComboAddress* rem, PacketBuffer& data_, bool isTcp, const struct timespec* queryTime_): DNSQuestion(name, type, class_, lc, rem, data_, isTcp, queryTime_) { } DNSResponse(const DNSResponse&) = delete; DNSResponse& operator=(const DNSResponse&) = delete; @@ -1211,15 +1212,15 @@ void setLuaSideEffect(); // set to report a side effect, cancelling all _no_ s bool getLuaNoSideEffect(); // set if there were only explicit declarations of _no_ side effect void resetLuaSideEffect(); // reset to indeterminate state -bool responseContentMatches(const std::vector& response, const DNSName& qname, const uint16_t qtype, const uint16_t qclass, const ComboAddress& remote, unsigned int& qnameWireLength); -bool processResponse(std::vector& response, LocalStateHolder >& localRespRulactions, DNSResponse& dr, bool muted); +bool responseContentMatches(const PacketBuffer& response, const DNSName& qname, const uint16_t qtype, const uint16_t qclass, const ComboAddress& remote, unsigned int& qnameWireLength); +bool processResponse(PacketBuffer& response, LocalStateHolder >& localRespRulactions, DNSResponse& dr, bool muted); bool processRulesResult(const DNSAction::Action& action, DNSQuestion& dq, std::string& ruleresult, bool& drop); bool checkQueryHeaders(const struct dnsheader* dh); extern std::vector> g_dnsCryptLocals; -int handleDNSCryptQuery(std::vector& packet, std::shared_ptr& query, bool tcp, time_t now, std::vector& response); -bool checkDNSCryptQuery(const ClientState& cs, std::vector& query, std::shared_ptr& dnsCryptQuery, time_t now, bool tcp); +int handleDNSCryptQuery(PacketBuffer& packet, std::shared_ptr& query, bool tcp, time_t now, PacketBuffer& response); +bool checkDNSCryptQuery(const ClientState& cs, PacketBuffer& query, std::shared_ptr& dnsCryptQuery, time_t now, bool tcp); uint16_t getRandomDNSID(); @@ -1237,8 +1238,8 @@ static const size_t s_maxPacketCacheEntrySize{4096}; // don't cache responses la enum class ProcessQueryResult { Drop, SendAnswer, PassToBackend }; ProcessQueryResult processQuery(DNSQuestion& dq, ClientState& cs, LocalHolders& holders, std::shared_ptr& selectedBackend); -DNSResponse makeDNSResponseFromIDState(IDState& ids, std::vector& data, bool isTCP); +DNSResponse makeDNSResponseFromIDState(IDState& ids, PacketBuffer& data, bool isTCP); void setIDStateFromDNSQuestion(IDState& ids, DNSQuestion& dq, DNSName&& qname); int pickBackendSocketForSending(std::shared_ptr& state); -ssize_t udpClientSendRequestToBackend(const std::shared_ptr& ss, const int sd, const std::vector& request, bool healthCheck = false); +ssize_t udpClientSendRequestToBackend(const std::shared_ptr& ss, const int sd, const PacketBuffer& request, bool healthCheck = false); diff --git a/pdns/dnsdistdist/Makefile.am b/pdns/dnsdistdist/Makefile.am index d912fb859f3a..812d8e1e011d 100644 --- a/pdns/dnsdistdist/Makefile.am +++ b/pdns/dnsdistdist/Makefile.am @@ -191,6 +191,7 @@ dnsdist_SOURCES = \ misc.cc misc.hh \ mplexer.hh \ namespaces.hh \ + noinitvector.hh \ packetcache.hh \ pdnsexception.hh \ pollmplexer.cc \ @@ -247,6 +248,7 @@ testrunner_SOURCES = \ iputils.cc iputils.hh \ misc.cc misc.hh \ namespaces.hh \ + noinitvector.hh \ pdnsexception.hh \ pollmplexer.cc \ proxy-protocol.cc proxy-protocol.hh \ diff --git a/pdns/dnsdistdist/dnsdist-healthchecks.cc b/pdns/dnsdistdist/dnsdist-healthchecks.cc index e66a45ea26e4..395a500a1d0e 100644 --- a/pdns/dnsdistdist/dnsdist-healthchecks.cc +++ b/pdns/dnsdistdist/dnsdist-healthchecks.cc @@ -202,8 +202,8 @@ bool queueHealthCheck(std::shared_ptr& mplexer, const std::shared checkClass = std::get<2>(ret); } - vector packet; - DNSPacketWriter dpw(packet, checkName, checkType, checkClass); + PacketBuffer packet; + GenericDNSPacketWriter dpw(packet, checkName, checkType, checkClass); dnsheader * requestHeader = dpw.getHeader(); *requestHeader = checkHeader; diff --git a/pdns/dnsdistdist/dnsdist-idstate.cc b/pdns/dnsdistdist/dnsdist-idstate.cc index 9db149ada414..ef91d77d96dc 100644 --- a/pdns/dnsdistdist/dnsdist-idstate.cc +++ b/pdns/dnsdistdist/dnsdist-idstate.cc @@ -1,7 +1,7 @@ #include "dnsdist.hh" -DNSResponse makeDNSResponseFromIDState(IDState& ids, std::vector& data, bool isTCP) +DNSResponse makeDNSResponseFromIDState(IDState& ids, PacketBuffer& data, bool isTCP) { DNSResponse dr(&ids.qname, ids.qtype, ids.qclass, &ids.origDest, &ids.origRemote, data, isTCP, &ids.sentTime.d_start); dr.origFlags = ids.origFlags; diff --git a/pdns/dnsdistdist/dnsdist-lua-ffi.cc b/pdns/dnsdistdist/dnsdist-lua-ffi.cc index 4a96a208d8d0..602aafa466fd 100644 --- a/pdns/dnsdistdist/dnsdist-lua-ffi.cc +++ b/pdns/dnsdistdist/dnsdist-lua-ffi.cc @@ -356,7 +356,7 @@ void dnsdist_ffi_dnsquestion_set_http_response(dnsdist_ffi_dnsquestion_t* dq, ui } #ifdef HAVE_DNS_OVER_HTTPS - std::vector bodyVect(body, body + bodyLen); + PacketBuffer bodyVect(body, body + bodyLen); dq->dq->du->setHTTPResponse(statusCode, std::move(bodyVect), contentType); dq->dq->getHeader()->qr = true; #endif diff --git a/pdns/dnsdistdist/dnsdist-proxy-protocol.cc b/pdns/dnsdistdist/dnsdist-proxy-protocol.cc index eb10ca73736f..0a3d330e90a0 100644 --- a/pdns/dnsdistdist/dnsdist-proxy-protocol.cc +++ b/pdns/dnsdistdist/dnsdist-proxy-protocol.cc @@ -42,7 +42,7 @@ bool addProxyProtocol(DNSQuestion& dq) return addProxyProtocol(dq, payload); } -bool addProxyProtocol(std::vector& buffer, const std::string& payload) +bool addProxyProtocol(PacketBuffer& buffer, const std::string& payload) { auto previousSize = buffer.size(); if (payload.size() > (std::numeric_limits::max() - previousSize)) { @@ -54,7 +54,7 @@ bool addProxyProtocol(std::vector& buffer, const std::string& payload) return true; } -bool addProxyProtocol(std::vector& buffer, bool tcp, const ComboAddress& source, const ComboAddress& destination, const std::vector& values) +bool addProxyProtocol(PacketBuffer& buffer, bool tcp, const ComboAddress& source, const ComboAddress& destination, const std::vector& values) { auto payload = makeProxyHeader(tcp, source, destination, values); return addProxyProtocol(buffer, payload); diff --git a/pdns/dnsdistdist/dnsdist-proxy-protocol.hh b/pdns/dnsdistdist/dnsdist-proxy-protocol.hh index a218a403d411..9ca60eb361f5 100644 --- a/pdns/dnsdistdist/dnsdist-proxy-protocol.hh +++ b/pdns/dnsdistdist/dnsdist-proxy-protocol.hh @@ -27,5 +27,5 @@ std::string getProxyProtocolPayload(const DNSQuestion& dq); bool addProxyProtocol(DNSQuestion& dq); bool addProxyProtocol(DNSQuestion& dq, const std::string& payload); -bool addProxyProtocol(std::vector& buffer, const std::string& payload); -bool addProxyProtocol(std::vector& buffer, bool tcp, const ComboAddress& source, const ComboAddress& destination, const std::vector& values); +bool addProxyProtocol(PacketBuffer& buffer, const std::string& payload); +bool addProxyProtocol(PacketBuffer& buffer, bool tcp, const ComboAddress& source, const ComboAddress& destination, const std::vector& values); diff --git a/pdns/dnsdistdist/dnsdist-secpoll.cc b/pdns/dnsdistdist/dnsdist-secpoll.cc index 358f943b18ba..8737dec4798b 100644 --- a/pdns/dnsdistdist/dnsdist-secpoll.cc +++ b/pdns/dnsdistdist/dnsdist-secpoll.cc @@ -91,7 +91,7 @@ static std::string getFirstTXTAnswer(const std::string& answer) static std::string getSecPollStatus(const std::string& queriedName, int timeout=2) { const DNSName& sentName = DNSName(queriedName); - vector packet; + std::vector packet; DNSPacketWriter pw(packet, sentName, QType::TXT); pw.getHeader()->id = getRandomDNSID(); pw.getHeader()->rd = 1; diff --git a/pdns/dnsdistdist/dnsdist-tcp-downstream.cc b/pdns/dnsdistdist/dnsdist-tcp-downstream.cc index 622b6a93316e..b16195fa1049 100644 --- a/pdns/dnsdistdist/dnsdist-tcp-downstream.cc +++ b/pdns/dnsdistdist/dnsdist-tcp-downstream.cc @@ -48,7 +48,7 @@ IOState TCPConnectionToBackend::queueNextQuery(std::shared_ptr& buffer, size_t& pos, size_t toRead) +static IOState tryRead(int fd, PacketBuffer& buffer, size_t& pos, size_t toRead) { if (buffer.size() < (pos + toRead)) { throw std::out_of_range("Calling tryRead() with a too small buffer (" + std::to_string(buffer.size()) + ") for a read of " + std::to_string(toRead) + " bytes starting at " + std::to_string(pos)); diff --git a/pdns/dnsdistdist/dnsdist-tcp-downstream.hh b/pdns/dnsdistdist/dnsdist-tcp-downstream.hh index 48c0901d9bf6..9bb64909b8d1 100644 --- a/pdns/dnsdistdist/dnsdist-tcp-downstream.hh +++ b/pdns/dnsdistdist/dnsdist-tcp-downstream.hh @@ -12,12 +12,12 @@ struct TCPQuery { } - TCPQuery(std::vector&& buffer, IDState&& state): d_idstate(std::move(state)), d_buffer(std::move(buffer)) + TCPQuery(PacketBuffer&& buffer, IDState&& state): d_idstate(std::move(state)), d_buffer(std::move(buffer)) { } IDState d_idstate; - std::vector d_buffer; + PacketBuffer d_buffer; }; class TCPConnectionToBackend; @@ -30,7 +30,7 @@ struct TCPResponse : public TCPQuery memset(&d_cleartextDH, 0, sizeof(d_cleartextDH)); } - TCPResponse(std::vector&& buffer, IDState&& state, std::shared_ptr conn): TCPQuery(std::move(buffer), std::move(state)), d_connection(conn) + TCPResponse(PacketBuffer&& buffer, IDState&& state, std::shared_ptr conn): TCPQuery(std::move(buffer), std::move(state)), d_connection(conn) { memset(&d_cleartextDH, 0, sizeof(d_cleartextDH)); } @@ -214,7 +214,7 @@ private: static const uint16_t s_xfrID; - std::vector d_responseBuffer; + PacketBuffer d_responseBuffer; std::deque d_pendingQueries; std::unordered_map d_pendingResponses; std::unique_ptr d_socket{nullptr}; diff --git a/pdns/dnsdistdist/dnsdist-tcp-upstream.hh b/pdns/dnsdistdist/dnsdist-tcp-upstream.hh index f5e063cae317..58210dc40ebb 100644 --- a/pdns/dnsdistdist/dnsdist-tcp-upstream.hh +++ b/pdns/dnsdistdist/dnsdist-tcp-upstream.hh @@ -199,7 +199,7 @@ public: enum class State { doingHandshake, readingQuerySize, readingQuery, sendingResponse, idle /* in case of XFR, we stop processing queries */ }; std::map, std::deque>> d_activeConnectionsToBackend; - std::vector d_buffer; + PacketBuffer d_buffer; std::deque d_queuedResponses; TCPClientThreadData& d_threadData; TCPResponse d_currentResponse; diff --git a/pdns/dnsdistdist/doh.cc b/pdns/dnsdistdist/doh.cc index de8b322733e2..60c8487b96fa 100644 --- a/pdns/dnsdistdist/doh.cc +++ b/pdns/dnsdistdist/doh.cc @@ -328,7 +328,7 @@ static const std::string& getReasonFromStatusCode(uint16_t statusCode) } /* Always called from the main DoH thread */ -static void handleResponse(DOHFrontend& df, st_h2o_req_t* req, uint16_t statusCode, const std::vector& response, const std::vector>& customResponseHeaders, const std::string& contentType, bool addContentType) +static void handleResponse(DOHFrontend& df, st_h2o_req_t* req, uint16_t statusCode, const PacketBuffer& response, const std::vector>& customResponseHeaders, const std::string& contentType, bool addContentType) { constexpr int overwrite_if_exists = 1; constexpr int maybe_token = 1; @@ -654,7 +654,7 @@ static void on_generator_dispose(void *_self) /* This executes in the main DoH thread. We allocate a DOHUnit and send it to dnsdistclient() function in the doh client thread via a pipe */ -static void doh_dispatch_query(DOHServerConfig* dsc, h2o_handler_t* self, h2o_req_t* req, std::vector&& query, const ComboAddress& local, const ComboAddress& remote, std::string&& path) +static void doh_dispatch_query(DOHServerConfig* dsc, h2o_handler_t* self, h2o_req_t* req, PacketBuffer&& query, const ComboAddress& local, const ComboAddress& remote, std::string&& path) { try { /* we only parse it there as a sanity check, we will parse it again later */ @@ -858,7 +858,7 @@ try else ++dsc->df->d_http1Stats.d_nbQueries; - std::vector query; + PacketBuffer query; /* We reserve at least 512 additional bytes to be able to add EDNS, but we also want at least s_maxPacketCacheEntrySize bytes to be able to fill the answer from the packet cache */ query.reserve(std::max(req->entity.len + 512, s_maxPacketCacheEntrySize)); @@ -885,7 +885,7 @@ try break; } - std::vector decoded; + PacketBuffer decoded; /* rough estimate so we hopefully don't need a new allocation later */ /* We reserve at least 512 additional bytes to be able to add EDNS, but we also want @@ -1036,7 +1036,7 @@ std::string DOHUnit::getHTTPQueryString() const } } -void DOHUnit::setHTTPResponse(uint16_t statusCode, std::vector&& body_, const std::string& contentType_) +void DOHUnit::setHTTPResponse(uint16_t statusCode, PacketBuffer&& body_, const std::string& contentType_) { status_code = statusCode; response = std::move(body_); diff --git a/pdns/dnsdistdist/noinitvector.hh b/pdns/dnsdistdist/noinitvector.hh new file mode 120000 index 000000000000..ee1de0963f4f --- /dev/null +++ b/pdns/dnsdistdist/noinitvector.hh @@ -0,0 +1 @@ +../noinitvector.hh \ No newline at end of file diff --git a/pdns/dnsdistdist/tcpiohandler.cc b/pdns/dnsdistdist/tcpiohandler.cc index c1ff709344e5..7c9aae7c5376 100644 --- a/pdns/dnsdistdist/tcpiohandler.cc +++ b/pdns/dnsdistdist/tcpiohandler.cc @@ -144,7 +144,7 @@ class OpenSSLTLSConnection: public TLSConnection } } - IOState tryWrite(std::vector& buffer, size_t& pos, size_t toWrite) override + IOState tryWrite(PacketBuffer& buffer, size_t& pos, size_t toWrite) override { do { int res = SSL_write(d_conn.get(), reinterpret_cast(&buffer.at(pos)), static_cast(toWrite - pos)); @@ -159,7 +159,7 @@ class OpenSSLTLSConnection: public TLSConnection return IOState::Done; } - IOState tryRead(std::vector& buffer, size_t& pos, size_t toRead) override + IOState tryRead(PacketBuffer& buffer, size_t& pos, size_t toRead) override { do { int res = SSL_read(d_conn.get(), reinterpret_cast(&buffer.at(pos)), static_cast(toRead - pos)); @@ -572,7 +572,7 @@ class GnuTLSConnection: public TLSConnection throw std::runtime_error("Error accepting a new connection"); } - IOState tryWrite(std::vector& buffer, size_t& pos, size_t toWrite) override + IOState tryWrite(PacketBuffer& buffer, size_t& pos, size_t toWrite) override { do { ssize_t res = gnutls_record_send(d_conn.get(), reinterpret_cast(&buffer.at(pos)), toWrite - pos); @@ -596,7 +596,7 @@ class GnuTLSConnection: public TLSConnection return IOState::Done; } - IOState tryRead(std::vector& buffer, size_t& pos, size_t toRead) override + IOState tryRead(PacketBuffer& buffer, size_t& pos, size_t toRead) override { do { ssize_t res = gnutls_record_recv(d_conn.get(), reinterpret_cast(&buffer.at(pos)), toRead - pos); diff --git a/pdns/dnsdistdist/test-dnsdistkvs_cc.cc b/pdns/dnsdistdist/test-dnsdistkvs_cc.cc index 783e9fabf01d..04f19ce140d6 100644 --- a/pdns/dnsdistdist/test-dnsdistkvs_cc.cc +++ b/pdns/dnsdistdist/test-dnsdistkvs_cc.cc @@ -233,7 +233,7 @@ BOOST_AUTO_TEST_CASE(test_LMDB) { uint16_t qclass = QClass::IN; ComboAddress lc("192.0.2.1:53"); ComboAddress rem("192.0.2.128:42"); - std::vector packet(sizeof(dnsheader)); + PacketBuffer packet(sizeof(dnsheader)); bool isTcp = false; struct timespec queryRealTime; gettime(&queryRealTime, true); @@ -288,7 +288,7 @@ BOOST_AUTO_TEST_CASE(test_CDB) { uint16_t qclass = QClass::IN; ComboAddress lc("192.0.2.1:53"); ComboAddress rem("192.0.2.128:42"); - std::vector packet(sizeof(dnsheader)); + PacketBuffer packet(sizeof(dnsheader)); bool isTcp = false; struct timespec queryRealTime; gettime(&queryRealTime, true); diff --git a/pdns/dnsdistdist/test-dnsdistlbpolicies_cc.cc b/pdns/dnsdistdist/test-dnsdistlbpolicies_cc.cc index 67fdae00c926..ce76c8bab1f9 100644 --- a/pdns/dnsdistdist/test-dnsdistlbpolicies_cc.cc +++ b/pdns/dnsdistdist/test-dnsdistlbpolicies_cc.cc @@ -59,7 +59,7 @@ std::string DOHUnit::getHTTPQueryString() const return ""; } -void DOHUnit::setHTTPResponse(uint16_t statusCode, std::vector&& body_, const std::string& contentType_) +void DOHUnit::setHTTPResponse(uint16_t statusCode, PacketBuffer&& body_, const std::string& contentType_) { } #endif /* HAVE_DNS_OVER_HTTPS */ @@ -91,7 +91,7 @@ static DNSQuestion getDQ(const DNSName* providedName = nullptr) static const ComboAddress lc("127.0.0.1:53"); static const ComboAddress rem("192.0.2.1:42"); static struct timespec queryRealTime; - static std::vector packet(sizeof(dnsheader)); + static PacketBuffer packet(sizeof(dnsheader)); uint16_t qtype = QType::A; uint16_t qclass = QClass::IN; diff --git a/pdns/dnsdistdist/test-dnsdistrules_cc.cc b/pdns/dnsdistdist/test-dnsdistrules_cc.cc index bc396d8b7d2b..f7f939944c73 100644 --- a/pdns/dnsdistdist/test-dnsdistrules_cc.cc +++ b/pdns/dnsdistdist/test-dnsdistrules_cc.cc @@ -22,7 +22,7 @@ BOOST_AUTO_TEST_CASE(test_MaxQPSIPRule) { uint16_t qclass = QClass::IN; ComboAddress lc("127.0.0.1:53"); ComboAddress rem("192.0.2.1:42"); - std::vector packet(sizeof(dnsheader)); + PacketBuffer packet(sizeof(dnsheader)); bool isTcp = false; struct timespec queryRealTime; gettime(&queryRealTime, true); diff --git a/pdns/dnswriter.cc b/pdns/dnswriter.cc index adad9e021430..09f195db853e 100644 --- a/pdns/dnswriter.cc +++ b/pdns/dnswriter.cc @@ -41,7 +41,7 @@ */ -DNSPacketWriter::DNSPacketWriter(vector& content, const DNSName& qname, uint16_t qtype, uint16_t qclass, uint8_t opcode) +template GenericDNSPacketWriter::GenericDNSPacketWriter(Container& content, const DNSName& qname, uint16_t qtype, uint16_t qclass, uint8_t opcode) : d_content(content), d_qname(qname), d_canonic(false), d_lowerCase(false) { d_content.clear(); @@ -68,13 +68,13 @@ DNSPacketWriter::DNSPacketWriter(vector& content, const DNSName& qname, d_rollbackmarker = 0; } -dnsheader* DNSPacketWriter::getHeader() +template dnsheader* GenericDNSPacketWriter::getHeader() { return reinterpret_cast(&*d_content.begin()); } -void DNSPacketWriter::startRecord(const DNSName& name, uint16_t qtype, uint32_t ttl, uint16_t qclass, DNSResourceRecord::Place place, bool compress) +template void GenericDNSPacketWriter::startRecord(const DNSName& name, uint16_t qtype, uint32_t ttl, uint16_t qclass, DNSResourceRecord::Place place, bool compress) { d_compress = compress; commit(); @@ -95,7 +95,7 @@ void DNSPacketWriter::startRecord(const DNSName& name, uint16_t qtype, uint32_t d_sor=d_content.size(); // this will remind us where to stuff the record size } -void DNSPacketWriter::addOpt(const uint16_t udpsize, const uint16_t extRCode, const uint16_t ednsFlags, const optvect_t& options, const uint8_t version) +template void GenericDNSPacketWriter::addOpt(const uint16_t udpsize, const uint16_t extRCode, const uint16_t ednsFlags, const optvect_t& options, const uint8_t version) { uint32_t ttl=0; @@ -129,7 +129,7 @@ void DNSPacketWriter::addOpt(const uint16_t udpsize, const uint16_t extRCode, co } } -void DNSPacketWriter::xfr48BitInt(uint64_t val) +template void GenericDNSPacketWriter::xfr48BitInt(uint64_t val) { unsigned char bytes[6]; uint16_t theLeft = htons((val >> 32)&0xffffU); @@ -141,21 +141,21 @@ void DNSPacketWriter::xfr48BitInt(uint64_t val) } -void DNSPacketWriter::xfr32BitInt(uint32_t val) +template void GenericDNSPacketWriter::xfr32BitInt(uint32_t val) { uint32_t rval=htonl(val); uint8_t* ptr=reinterpret_cast(&rval); d_content.insert(d_content.end(), ptr, ptr+4); } -void DNSPacketWriter::xfr16BitInt(uint16_t val) +template void GenericDNSPacketWriter::xfr16BitInt(uint16_t val) { uint16_t rval=htons(val); uint8_t* ptr=reinterpret_cast(&rval); d_content.insert(d_content.end(), ptr, ptr+2); } -void DNSPacketWriter::xfr8BitInt(uint8_t val) +template void GenericDNSPacketWriter::xfr8BitInt(uint8_t val) { d_content.push_back(val); } @@ -174,7 +174,7 @@ void DNSPacketWriter::xfr8BitInt(uint8_t val) "blah" -> blah "blah\"blah" -> blah"blah */ -void DNSPacketWriter::xfrText(const string& text, bool, bool lenField) +template void GenericDNSPacketWriter::xfrText(const string& text, bool, bool lenField) { if(text.empty()) { d_content.push_back(0); @@ -188,7 +188,7 @@ void DNSPacketWriter::xfrText(const string& text, bool, bool lenField) } } -void DNSPacketWriter::xfrUnquotedText(const string& text, bool lenField) +template void GenericDNSPacketWriter::xfrUnquotedText(const string& text, bool lenField) { if(text.empty()) { d_content.push_back(0); @@ -202,7 +202,7 @@ void DNSPacketWriter::xfrUnquotedText(const string& text, bool lenField) static constexpr bool l_verbose=false; static constexpr uint16_t maxCompressionOffset=16384; -uint16_t DNSPacketWriter::lookupName(const DNSName& name, uint16_t* matchLen) +template uint16_t GenericDNSPacketWriter::lookupName(const DNSName& name, uint16_t* matchLen) { // iterate over the written labels, see if we find a match const auto& raw = name.getStorage(); @@ -315,7 +315,7 @@ uint16_t DNSPacketWriter::lookupName(const DNSName& name, uint16_t* matchLen) return bestpos; } // this is the absolute hottest function in the pdns recursor -void DNSPacketWriter::xfrName(const DNSName& name, bool compress, bool) +template void GenericDNSPacketWriter::xfrName(const DNSName& name, bool compress, bool) { if(l_verbose) cout<<"Wants to write "<; + + diff --git a/pdns/dnswriter.hh b/pdns/dnswriter.hh index 25cfd6f3e5e5..aef99ae49d7d 100644 --- a/pdns/dnswriter.hh +++ b/pdns/dnswriter.hh @@ -57,12 +57,12 @@ */ -class DNSPacketWriter : public boost::noncopyable +template class GenericDNSPacketWriter : public boost::noncopyable { public: //! Start a DNS Packet in the vector passed, with question qname, qtype and qclass - DNSPacketWriter(vector& content, const DNSName& qname, uint16_t qtype, uint16_t qclass=QClass::IN, uint8_t opcode=0); + GenericDNSPacketWriter(Container& content, const DNSName& qname, uint16_t qtype, uint16_t qclass=QClass::IN, uint8_t opcode=0); /** Start a new DNS record within this packet for namq, qtype, ttl, class and in the requested place. Note that packets can only be written in natural order - ANSWER, AUTHORITY, ADDITIONAL */ @@ -146,7 +146,7 @@ public: { d_lowerCase=val; } - vector & getContent() + Container& getContent() { return d_content; } @@ -162,7 +162,7 @@ private: uint16_t d_sor; uint16_t d_rollbackmarker; // start of last complete packet, for rollback - vector & d_content; + Container& d_content; DNSName d_qname; uint16_t d_truncatemarker; // end of header, for truncate @@ -170,6 +170,8 @@ private: bool d_canonic, d_lowerCase, d_compress{false}; }; +using DNSPacketWriter = GenericDNSPacketWriter>; + typedef vector > labelparts_t; // bool labeltokUnescape(labelparts_t& parts, const DNSName& label); std::vector segmentDNSText(const string& text); // from dnslabeltext.rl diff --git a/pdns/doh.hh b/pdns/doh.hh index ed17ad26041c..5327457d7fbe 100644 --- a/pdns/doh.hh +++ b/pdns/doh.hh @@ -22,13 +22,14 @@ #pragma once #include "iputils.hh" #include "libssl.hh" +#include "noinitvector.hh" struct DOHServerConfig; class DOHResponseMapEntry { public: - DOHResponseMapEntry(const std::string& regex, uint16_t status, const std::vector& content, const boost::optional>>& headers): d_regex(regex), d_customHeaders(headers), d_content(content), d_status(status) + DOHResponseMapEntry(const std::string& regex, uint16_t status, const PacketBuffer& content, const boost::optional>>& headers): d_regex(regex), d_customHeaders(headers), d_content(content), d_status(status) { if (status >= 400 && !d_content.empty() && d_content.at(d_content.size() -1) != 0) { // we need to make sure it's null-terminated @@ -46,7 +47,7 @@ public: return d_status; } - const std::vector& getContent() const + const PacketBuffer& getContent() const { return d_content; } @@ -59,7 +60,7 @@ public: private: Regex d_regex; boost::optional>> d_customHeaders; - std::vector d_content; + PacketBuffer d_content; uint16_t d_status; }; @@ -189,8 +190,8 @@ struct DOHUnit } std::vector> headers; - std::vector query; - std::vector response; + PacketBuffer query; + PacketBuffer response; std::string sni; std::string path; std::string scheme; @@ -219,7 +220,7 @@ struct DOHUnit std::string getHTTPScheme() const; std::string getHTTPQueryString() const; std::unordered_map getHTTPHeaders() const; - void setHTTPResponse(uint16_t statusCode, std::vector&& body, const std::string& contentType=""); + void setHTTPResponse(uint16_t statusCode, PacketBuffer&& body, const std::string& contentType=""); }; #endif /* HAVE_DNS_OVER_HTTPS */ diff --git a/pdns/fuzz_dnsdistcache.cc b/pdns/fuzz_dnsdistcache.cc index 1b12f356025a..eb68950bddd1 100644 --- a/pdns/fuzz_dnsdistcache.cc +++ b/pdns/fuzz_dnsdistcache.cc @@ -43,7 +43,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { uint16_t qtype; uint16_t qclass; unsigned int consumed; - std::vector vect(data, data+size); + PacketBuffer vect(data, data+size); const DNSName qname(reinterpret_cast(data), size, sizeof(dnsheader), false, &qtype, &qclass, &consumed); pcSkipCookies.getKey(qname.getStorage(), consumed, vect, false); pcHashCookies.getKey(qname.getStorage(), consumed, vect, false); diff --git a/pdns/noinitvector.hh b/pdns/noinitvector.hh new file mode 100644 index 000000000000..cc7efc30e0af --- /dev/null +++ b/pdns/noinitvector.hh @@ -0,0 +1,67 @@ +#pragma once + +#include +#include +#include +#include + +// based on boost::core::noinit_adaptor +// The goal is to avoid initialization of the content of a container, +// because setting several kB of uint8_t to 0 has a real cost if you +// do 100k times per second. +template +struct noinit_adaptor: Allocator +{ + template + struct rebind { + typedef noinit_adaptor::template + rebind_alloc > other; + }; + + noinit_adaptor(): Allocator() { } + + template + noinit_adaptor(U&& u) noexcept : Allocator(std::forward(u)) { } + + template + noinit_adaptor(const noinit_adaptor& u) noexcept : Allocator(static_cast(u)) { } + + template + void construct(U* p) { + ::new((void*)p) U; + } + + template + void construct(U* p, V&& v, Args&&... args) { + ::new((void*)p) U(std::forward(v), std::forward(args)...); + } + + template + void destroy(U* p) { + p->~U(); + } +}; + +template +inline bool operator==(const noinit_adaptor& lhs, + const noinit_adaptor& rhs) noexcept +{ + return static_cast(lhs) == static_cast(rhs); +} + +template +inline bool operator!=(const noinit_adaptor& lhs, + const noinit_adaptor& rhs) noexcept +{ + return !(lhs == rhs); +} + +template +inline noinit_adaptor noinit_adapt(const Allocator& a) noexcept +{ + return noinit_adaptor(a); +} + +template using NoInitVector = std::vector>>; + +using PacketBuffer = NoInitVector; diff --git a/pdns/recursordist/Makefile.am b/pdns/recursordist/Makefile.am index 725cf5c3cbda..f3757f165cb8 100644 --- a/pdns/recursordist/Makefile.am +++ b/pdns/recursordist/Makefile.am @@ -135,6 +135,7 @@ pdns_recursor_SOURCES = \ mtasker_context.cc mtasker_context.hh \ namespaces.hh \ negcache.hh negcache.cc \ + noinitvector.hh \ nsecrecords.cc \ opensslsigners.cc opensslsigners.hh \ packetcache.hh \ diff --git a/pdns/recursordist/noinitvector.hh b/pdns/recursordist/noinitvector.hh new file mode 120000 index 000000000000..ee1de0963f4f --- /dev/null +++ b/pdns/recursordist/noinitvector.hh @@ -0,0 +1 @@ +../noinitvector.hh \ No newline at end of file diff --git a/pdns/sodcrypto.cc b/pdns/sodcrypto.cc index 5c96e1a1625e..b92c6e0e53bb 100644 --- a/pdns/sodcrypto.cc +++ b/pdns/sodcrypto.cc @@ -21,6 +21,7 @@ */ #include #include "namespaces.hh" +#include "noinitvector.hh" #include "misc.hh" #include "base64.hh" #include "sodcrypto.hh" @@ -292,6 +293,7 @@ template int B64Decode(const std::string& strInput, Containe } template int B64Decode>(const std::string& strInput, std::vector& strOutput); +template int B64Decode(const std::string& strInput, PacketBuffer& strOutput); template int B64Decode(const std::string& strInput, std::string& strOutput); /* diff --git a/pdns/tcpiohandler.hh b/pdns/tcpiohandler.hh index a5e83208986e..98f1e8ed5555 100644 --- a/pdns/tcpiohandler.hh +++ b/pdns/tcpiohandler.hh @@ -4,6 +4,7 @@ #include "libssl.hh" #include "misc.hh" +#include "noinitvector.hh" enum class IOState { Done, NeedRead, NeedWrite }; @@ -15,8 +16,8 @@ public: virtual IOState tryHandshake() = 0; virtual size_t read(void* buffer, size_t bufferSize, unsigned int readTimeout, unsigned int totalTimeout=0) = 0; virtual size_t write(const void* buffer, size_t bufferSize, unsigned int writeTimeout) = 0; - virtual IOState tryWrite(std::vector& buffer, size_t& pos, size_t toWrite) = 0; - virtual IOState tryRead(std::vector& buffer, size_t& pos, size_t toRead) = 0; + virtual IOState tryWrite(PacketBuffer& buffer, size_t& pos, size_t toWrite) = 0; + virtual IOState tryRead(PacketBuffer& buffer, size_t& pos, size_t toRead) = 0; virtual bool hasBufferedData() const = 0; virtual std::string getServerNameIndication() const = 0; virtual LibsslTLSVersion getTLSVersion() const = 0; @@ -217,7 +218,7 @@ public: return Done when toRead bytes have been read, needRead or needWrite if the IO operation would block. */ - IOState tryRead(std::vector& buffer, size_t& pos, size_t toRead) + IOState tryRead(PacketBuffer& buffer, size_t& pos, size_t toRead) { if (buffer.size() < toRead || pos >= toRead) { throw std::out_of_range("Calling tryRead() with a too small buffer (" + std::to_string(buffer.size()) + ") for a read of " + std::to_string(toRead - pos) + " bytes starting at " + std::to_string(pos)); @@ -254,7 +255,7 @@ public: return Done when toWrite bytes have been written, needRead or needWrite if the IO operation would block. */ - IOState tryWrite(std::vector& buffer, size_t& pos, size_t toWrite) + IOState tryWrite(PacketBuffer& buffer, size_t& pos, size_t toWrite) { if (buffer.size() < toWrite || pos >= toWrite) { throw std::out_of_range("Calling tryWrite() with a too small buffer (" + std::to_string(buffer.size()) + ") for a write of " + std::to_string(toWrite - pos) + " bytes starting at " + std::to_string(pos)); diff --git a/pdns/test-dnscrypt_cc.cc b/pdns/test-dnscrypt_cc.cc index bbc08e83efc7..f3627971fa7f 100644 --- a/pdns/test-dnscrypt_cc.cc +++ b/pdns/test-dnscrypt_cc.cc @@ -49,8 +49,8 @@ BOOST_AUTO_TEST_CASE(DNSCryptPlaintextQuery) { auto ctx = std::make_shared("2.name", resolverCert, resolverPrivateKey); DNSName name("2.name."); - vector plainQuery; - DNSPacketWriter pw(plainQuery, name, QType::TXT, QClass::IN, 0); + PacketBuffer plainQuery; + GenericDNSPacketWriter pw(plainQuery, name, QType::TXT, QClass::IN, 0); pw.getHeader()->rd = 0; std::shared_ptr query = std::make_shared(ctx); @@ -59,7 +59,7 @@ BOOST_AUTO_TEST_CASE(DNSCryptPlaintextQuery) { BOOST_CHECK_EQUAL(query->isValid(), true); BOOST_CHECK_EQUAL(query->isEncrypted(), false); - std::vector response; + PacketBuffer response; query->getCertificateResponse(now, response); @@ -88,8 +88,8 @@ BOOST_AUTO_TEST_CASE(DNSCryptPlaintextQueryInvalidA) { DNSName name("2.name."); - vector plainQuery; - DNSPacketWriter pw(plainQuery, name, QType::A, QClass::IN, 0); + PacketBuffer plainQuery; + GenericDNSPacketWriter pw(plainQuery, name, QType::A, QClass::IN, 0); pw.getHeader()->rd = 0; std::shared_ptr query = std::make_shared(ctx); @@ -111,8 +111,8 @@ BOOST_AUTO_TEST_CASE(DNSCryptPlaintextQueryInvalidProviderName) { DNSName name("2.WRONG.name."); - vector plainQuery; - DNSPacketWriter pw(plainQuery, name, QType::TXT, QClass::IN, 0); + PacketBuffer plainQuery; + GenericDNSPacketWriter pw(plainQuery, name, QType::TXT, QClass::IN, 0); pw.getHeader()->rd = 0; std::shared_ptr query = std::make_shared(ctx); @@ -140,8 +140,8 @@ BOOST_AUTO_TEST_CASE(DNSCryptEncryptedQueryValid) { unsigned char clientNonce[DNSCRYPT_NONCE_SIZE / 2] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x08, 0x09, 0x0A, 0x0B }; DNSName name("www.powerdns.com."); - vector plainQuery; - DNSPacketWriter pw(plainQuery, name, QType::AAAA, QClass::IN, 0); + PacketBuffer plainQuery; + GenericDNSPacketWriter pw(plainQuery, name, QType::AAAA, QClass::IN, 0); pw.getHeader()->rd = 1; size_t requiredSize = plainQuery.size() + sizeof(DNSCryptQueryHeader) + DNSCRYPT_MAC_SIZE; if (requiredSize < DNSCryptQuery::s_minUDPLength) { @@ -194,8 +194,8 @@ BOOST_AUTO_TEST_CASE(DNSCryptEncryptedQueryValidButShort) { unsigned char clientNonce[DNSCRYPT_NONCE_SIZE / 2] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x08, 0x09, 0x0A, 0x0B }; DNSName name("www.powerdns.com."); - vector plainQuery; - DNSPacketWriter pw(plainQuery, name, QType::AAAA, QClass::IN, 0); + PacketBuffer plainQuery; + GenericDNSPacketWriter pw(plainQuery, name, QType::AAAA, QClass::IN, 0); pw.getHeader()->rd = 1; int res = ctx->encryptQuery(plainQuery, /* not enough room */ plainQuery.size(), clientPublicKey, clientPrivateKey, clientNonce, false, std::make_shared(resolverCert)); @@ -221,8 +221,8 @@ BOOST_AUTO_TEST_CASE(DNSCryptEncryptedQueryValidWithOldKey) { unsigned char clientNonce[DNSCRYPT_NONCE_SIZE / 2] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x08, 0x09, 0x0A, 0x0B }; DNSName name("www.powerdns.com."); - vector plainQuery; - DNSPacketWriter pw(plainQuery, name, QType::AAAA, QClass::IN, 0); + PacketBuffer plainQuery; + GenericDNSPacketWriter pw(plainQuery, name, QType::AAAA, QClass::IN, 0); pw.getHeader()->rd = 1; size_t requiredSize = plainQuery.size() + sizeof(DNSCryptQueryHeader) + DNSCRYPT_MAC_SIZE; @@ -279,8 +279,8 @@ BOOST_AUTO_TEST_CASE(DNSCryptEncryptedQueryInvalidWithWrongKey) { unsigned char clientNonce[DNSCRYPT_NONCE_SIZE / 2] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x08, 0x09, 0x0A, 0x0B }; DNSName name("www.powerdns.com."); - vector plainQuery; - DNSPacketWriter pw(plainQuery, name, QType::AAAA, QClass::IN, 0); + PacketBuffer plainQuery; + GenericDNSPacketWriter pw(plainQuery, name, QType::AAAA, QClass::IN, 0); pw.getHeader()->rd = 1; size_t initialSize = plainQuery.size(); diff --git a/pdns/test-dnsdist_cc.cc b/pdns/test-dnsdist_cc.cc index df7ca35099f7..f17e3992810f 100644 --- a/pdns/test-dnsdist_cc.cc +++ b/pdns/test-dnsdist_cc.cc @@ -42,7 +42,7 @@ BOOST_AUTO_TEST_SUITE(test_dnsdist_cc) static const uint16_t ECSSourcePrefixV4 = 24; static const uint16_t ECSSourcePrefixV6 = 56; -static void validateQuery(const std::vector& packet, bool hasEdns=true, bool hasXPF=false, uint16_t additionals=0, uint16_t answers=0, uint16_t authorities=0) +static void validateQuery(const PacketBuffer& packet, bool hasEdns=true, bool hasXPF=false, uint16_t additionals=0, uint16_t answers=0, uint16_t authorities=0) { MOADNSParser mdp(true, reinterpret_cast(packet.data()), packet.size()); @@ -55,14 +55,14 @@ static void validateQuery(const std::vector& packet, bool hasEdns=true, BOOST_CHECK_EQUAL(mdp.d_header.arcount, expectedARCount); } -static void validateECS(const std::vector& packet, const ComboAddress& expected) +static void validateECS(const PacketBuffer& packet, const ComboAddress& expected) { ComboAddress rem("::1"); unsigned int consumed = 0; uint16_t qtype; uint16_t qclass; DNSName qname(reinterpret_cast(packet.data()), packet.size(), sizeof(dnsheader), false, &qtype, &qclass, &consumed); - DNSQuestion dq(&qname, qtype, qclass, nullptr, &rem, const_cast&>(packet), false, nullptr); + DNSQuestion dq(&qname, qtype, qclass, nullptr, &rem, const_cast(packet), false, nullptr); BOOST_CHECK(parseEDNSOptions(dq)); BOOST_REQUIRE(dq.ednsOptions != nullptr); BOOST_CHECK_EQUAL(dq.ednsOptions->size(), 1U); @@ -76,7 +76,7 @@ static void validateECS(const std::vector& packet, const ComboAddress& BOOST_CHECK_EQUAL(expectedOption.substr(EDNS_OPTION_CODE_SIZE + EDNS_OPTION_LENGTH_SIZE), std::string(ecsOption->second.values.at(0).content, ecsOption->second.values.at(0).size)); } -static void validateResponse(const std::vector& packet, bool hasEdns, uint8_t additionalCount=0) +static void validateResponse(const PacketBuffer& packet, bool hasEdns, uint8_t additionalCount=0) { MOADNSParser mdp(false, reinterpret_cast(packet.data()), packet.size()); @@ -98,13 +98,13 @@ BOOST_AUTO_TEST_CASE(test_addXPF) ComboAddress remote; DNSName name("www.powerdns.com."); - vector query; - DNSPacketWriter pw(query, name, QType::A, QClass::IN, 0); + PacketBuffer query; + GenericDNSPacketWriter pw(query, name, QType::A, QClass::IN, 0); pw.getHeader()->rd = 1; - vector queryWithXPF; + PacketBuffer queryWithXPF; { - std::vector packet = query; + PacketBuffer packet = query; /* large enough packet */ unsigned int consumed = 0; @@ -122,7 +122,7 @@ BOOST_AUTO_TEST_CASE(test_addXPF) } { - std::vector packet = query; + PacketBuffer packet = query; /* packet is already too large for the 4096 limit over UDP */ packet.resize(4096); @@ -141,7 +141,7 @@ BOOST_AUTO_TEST_CASE(test_addXPF) } { - std::vector packet = query; + PacketBuffer packet = query; /* packet with trailing data (overriding it) */ unsigned int consumed = 0; @@ -176,13 +176,13 @@ BOOST_AUTO_TEST_CASE(addECSWithoutEDNS) string newECSOption; generateECSOption(remote, newECSOption, remote.sin4.sin_family == AF_INET ? ECSSourcePrefixV4 : ECSSourcePrefixV6); - vector query; - DNSPacketWriter pw(query, name, QType::A, QClass::IN, 0); + PacketBuffer query; + GenericDNSPacketWriter pw(query, name, QType::A, QClass::IN, 0); pw.getHeader()->rd = 1; uint16_t len = query.size(); /* large enough packet */ - std::vector packet = query; + PacketBuffer packet = query; unsigned int consumed = 0; uint16_t qtype; @@ -196,7 +196,7 @@ BOOST_AUTO_TEST_CASE(addECSWithoutEDNS) BOOST_CHECK_EQUAL(ecsAdded, true); validateQuery(packet); validateECS(packet, remote); - vector queryWithEDNS = packet; + PacketBuffer queryWithEDNS = packet; /* not large enough packet */ packet = query; @@ -245,8 +245,8 @@ BOOST_AUTO_TEST_CASE(addECSWithoutEDNSAlreadyParsed) ComboAddress remote("192.0.2.1"); DNSName name("www.powerdns.com."); - vector query; - DNSPacketWriter pw(query, name, QType::A, QClass::IN, 0); + PacketBuffer query; + GenericDNSPacketWriter pw(query, name, QType::A, QClass::IN, 0); pw.getHeader()->rd = 1; auto packet = query; @@ -301,8 +301,8 @@ BOOST_AUTO_TEST_CASE(addECSWithEDNSNoECS) { string newECSOption; generateECSOption(remote, newECSOption, remote.sin4.sin_family == AF_INET ? ECSSourcePrefixV4 : ECSSourcePrefixV6); - vector query; - DNSPacketWriter pw(query, name, QType::A, QClass::IN, 0); + PacketBuffer query; + GenericDNSPacketWriter pw(query, name, QType::A, QClass::IN, 0); pw.getHeader()->rd = 1; pw.addOpt(512, 0, 0); pw.commit(); @@ -345,8 +345,8 @@ BOOST_AUTO_TEST_CASE(addECSWithEDNSNoECSAlreadyParsed) { ComboAddress remote("2001:DB8::1"); DNSName name("www.powerdns.com."); - vector query; - DNSPacketWriter pw(query, name, QType::A, QClass::IN, 0); + PacketBuffer query; + GenericDNSPacketWriter pw(query, name, QType::A, QClass::IN, 0); pw.getHeader()->rd = 1; pw.addOpt(512, 0, 0); pw.commit(); @@ -403,13 +403,13 @@ BOOST_AUTO_TEST_CASE(replaceECSWithSameSize) { string newECSOption; generateECSOption(remote, newECSOption, remote.sin4.sin_family == AF_INET ? ECSSourcePrefixV4 : ECSSourcePrefixV6); - vector query; - DNSPacketWriter pw(query, name, QType::A, QClass::IN, 0); + PacketBuffer query; + GenericDNSPacketWriter pw(query, name, QType::A, QClass::IN, 0); pw.getHeader()->rd = 1; EDNSSubnetOpts ecsOpts; ecsOpts.source = Netmask(origRemote, ECSSourcePrefixV4); string origECSOption = makeEDNSSubnetOptsString(ecsOpts); - DNSPacketWriter::optvect_t opts; + GenericDNSPacketWriter::optvect_t opts; opts.push_back(make_pair(EDNSOptionCode::ECS, origECSOption)); pw.addOpt(512, 0, 0, opts); pw.commit(); @@ -438,13 +438,13 @@ BOOST_AUTO_TEST_CASE(replaceECSWithSameSizeAlreadyParsed) { DNSName name("www.powerdns.com."); ComboAddress origRemote("127.0.0.1"); - vector query; - DNSPacketWriter pw(query, name, QType::A, QClass::IN, 0); + PacketBuffer query; + GenericDNSPacketWriter pw(query, name, QType::A, QClass::IN, 0); pw.getHeader()->rd = 1; EDNSSubnetOpts ecsOpts; ecsOpts.source = Netmask(origRemote, ECSSourcePrefixV4); string origECSOption = makeEDNSSubnetOptsString(ecsOpts); - DNSPacketWriter::optvect_t opts; + GenericDNSPacketWriter::optvect_t opts; opts.push_back(make_pair(EDNSOptionCode::ECS, origECSOption)); pw.addOpt(512, 0, 0, opts); pw.commit(); @@ -483,13 +483,13 @@ BOOST_AUTO_TEST_CASE(replaceECSWithSmaller) { string newECSOption; generateECSOption(remote, newECSOption, remote.sin4.sin_family == AF_INET ? ECSSourcePrefixV4 : ECSSourcePrefixV6); - vector query; - DNSPacketWriter pw(query, name, QType::A, QClass::IN, 0); + PacketBuffer query; + GenericDNSPacketWriter pw(query, name, QType::A, QClass::IN, 0); pw.getHeader()->rd = 1; EDNSSubnetOpts ecsOpts; ecsOpts.source = Netmask(origRemote, 32); string origECSOption = makeEDNSSubnetOptsString(ecsOpts); - DNSPacketWriter::optvect_t opts; + GenericDNSPacketWriter::optvect_t opts; opts.push_back(make_pair(EDNSOptionCode::ECS, origECSOption)); pw.addOpt(512, 0, 0, opts); pw.commit(); @@ -519,15 +519,15 @@ BOOST_AUTO_TEST_CASE(replaceECSWithLarger) { string newECSOption; generateECSOption(remote, newECSOption, remote.sin4.sin_family == AF_INET ? ECSSourcePrefixV4 : ECSSourcePrefixV6); - vector query; - DNSPacketWriter pw(query, name, QType::A, QClass::IN, 0); + PacketBuffer query; + GenericDNSPacketWriter pw(query, name, QType::A, QClass::IN, 0); pw.getHeader()->rd = 1; EDNSSubnetOpts ecsOpts; // smaller (less specific so less bits) option static_assert(8 < ECSSourcePrefixV4, "The ECS scope should be smaller"); ecsOpts.source = Netmask(origRemote, 8); string origECSOption = makeEDNSSubnetOptsString(ecsOpts); - DNSPacketWriter::optvect_t opts; + GenericDNSPacketWriter::optvect_t opts; opts.push_back(make_pair(EDNSOptionCode::ECS, origECSOption)); pw.addOpt(512, 0, 0, opts); pw.commit(); @@ -574,13 +574,13 @@ BOOST_AUTO_TEST_CASE(replaceECSFollowedByTSIG) { string newECSOption; generateECSOption(remote, newECSOption, remote.sin4.sin_family == AF_INET ? ECSSourcePrefixV4 : ECSSourcePrefixV6); - vector query; - DNSPacketWriter pw(query, name, QType::A, QClass::IN, 0); + PacketBuffer query; + GenericDNSPacketWriter pw(query, name, QType::A, QClass::IN, 0); pw.getHeader()->rd = 1; EDNSSubnetOpts ecsOpts; ecsOpts.source = Netmask(origRemote, 8); string origECSOption = makeEDNSSubnetOptsString(ecsOpts); - DNSPacketWriter::optvect_t opts; + GenericDNSPacketWriter::optvect_t opts; opts.push_back(make_pair(EDNSOptionCode::ECS, origECSOption)); pw.addOpt(512, 0, 0, opts); pw.startRecord(DNSName("tsigname."), QType::TSIG, 0, QClass::ANY, DNSResourceRecord::ADDITIONAL, false); @@ -628,15 +628,15 @@ BOOST_AUTO_TEST_CASE(replaceECSAfterAN) { string newECSOption; generateECSOption(remote, newECSOption, remote.sin4.sin_family == AF_INET ? ECSSourcePrefixV4 : ECSSourcePrefixV6); - vector query; - DNSPacketWriter pw(query, name, QType::A, QClass::IN, 0); + PacketBuffer query; + GenericDNSPacketWriter pw(query, name, QType::A, QClass::IN, 0); pw.getHeader()->rd = 1; pw.startRecord(DNSName("powerdns.com."), QType::A, 0, QClass::IN, DNSResourceRecord::ANSWER, true); pw.commit(); EDNSSubnetOpts ecsOpts; ecsOpts.source = Netmask(origRemote, 8); string origECSOption = makeEDNSSubnetOptsString(ecsOpts); - DNSPacketWriter::optvect_t opts; + GenericDNSPacketWriter::optvect_t opts; opts.push_back(make_pair(EDNSOptionCode::ECS, origECSOption)); pw.addOpt(512, 0, 0, opts); pw.commit(); @@ -683,15 +683,15 @@ BOOST_AUTO_TEST_CASE(replaceECSAfterAuth) { string newECSOption; generateECSOption(remote, newECSOption, remote.sin4.sin_family == AF_INET ? ECSSourcePrefixV4 : ECSSourcePrefixV6); - vector query; - DNSPacketWriter pw(query, name, QType::A, QClass::IN, 0); + PacketBuffer query; + GenericDNSPacketWriter pw(query, name, QType::A, QClass::IN, 0); pw.getHeader()->rd = 1; pw.startRecord(DNSName("powerdns.com."), QType::A, 0, QClass::IN, DNSResourceRecord::AUTHORITY, true); pw.commit(); EDNSSubnetOpts ecsOpts; ecsOpts.source = Netmask(origRemote, 8); string origECSOption = makeEDNSSubnetOptsString(ecsOpts); - DNSPacketWriter::optvect_t opts; + GenericDNSPacketWriter::optvect_t opts; opts.push_back(make_pair(EDNSOptionCode::ECS, origECSOption)); pw.addOpt(512, 0, 0, opts); pw.commit(); @@ -738,13 +738,13 @@ BOOST_AUTO_TEST_CASE(replaceECSBetweenTwoRecords) { string newECSOption; generateECSOption(remote, newECSOption, remote.sin4.sin_family == AF_INET ? ECSSourcePrefixV4 : ECSSourcePrefixV6); - vector query; - DNSPacketWriter pw(query, name, QType::A, QClass::IN, 0); + PacketBuffer query; + GenericDNSPacketWriter pw(query, name, QType::A, QClass::IN, 0); pw.getHeader()->rd = 1; EDNSSubnetOpts ecsOpts; ecsOpts.source = Netmask(origRemote, 8); string origECSOption = makeEDNSSubnetOptsString(ecsOpts); - DNSPacketWriter::optvect_t opts; + GenericDNSPacketWriter::optvect_t opts; opts.push_back(make_pair(EDNSOptionCode::ECS, origECSOption)); pw.startRecord(DNSName("additional"), QType::A, 0, QClass::IN, DNSResourceRecord::ADDITIONAL, false); pw.xfr32BitInt(0x01020304); @@ -794,8 +794,8 @@ BOOST_AUTO_TEST_CASE(insertECSInEDNSBetweenTwoRecords) { string newECSOption; generateECSOption(remote, newECSOption, remote.sin4.sin_family == AF_INET ? ECSSourcePrefixV4 : ECSSourcePrefixV6); - vector query; - DNSPacketWriter pw(query, name, QType::A, QClass::IN, 0); + PacketBuffer query; + GenericDNSPacketWriter pw(query, name, QType::A, QClass::IN, 0); pw.getHeader()->rd = 1; pw.startRecord(DNSName("additional"), QType::A, 0, QClass::IN, DNSResourceRecord::ADDITIONAL, false); pw.xfr32BitInt(0x01020304); @@ -845,8 +845,8 @@ BOOST_AUTO_TEST_CASE(insertECSAfterTSIG) { string newECSOption; generateECSOption(remote, newECSOption, remote.sin4.sin_family == AF_INET ? ECSSourcePrefixV4 : ECSSourcePrefixV6); - vector query; - DNSPacketWriter pw(query, name, QType::A, QClass::IN, 0); + PacketBuffer query; + GenericDNSPacketWriter pw(query, name, QType::A, QClass::IN, 0); pw.getHeader()->rd = 1; pw.startRecord(DNSName("tsigname."), QType::TSIG, 0, QClass::ANY, DNSResourceRecord::ADDITIONAL, false); pw.commit(); @@ -889,8 +889,8 @@ BOOST_AUTO_TEST_CASE(insertECSAfterTSIG) { BOOST_AUTO_TEST_CASE(removeEDNSWhenFirst) { DNSName name("www.powerdns.com."); - vector response; - DNSPacketWriter pw(response, name, QType::A, QClass::IN, 0); + PacketBuffer response; + GenericDNSPacketWriter pw(response, name, QType::A, QClass::IN, 0); pw.getHeader()->qr = 1; pw.startRecord(name, QType::A, 3600, QClass::IN, DNSResourceRecord::ANSWER, true); pw.xfr32BitInt(0x01020304); @@ -900,7 +900,7 @@ BOOST_AUTO_TEST_CASE(removeEDNSWhenFirst) { pw.xfr32BitInt(0x01020304); pw.commit(); - vector newResponse; + PacketBuffer newResponse; int res = rewriteResponseWithoutEDNS(response, newResponse); BOOST_CHECK_EQUAL(res, 0); @@ -918,8 +918,8 @@ BOOST_AUTO_TEST_CASE(removeEDNSWhenFirst) { BOOST_AUTO_TEST_CASE(removeEDNSWhenIntermediary) { DNSName name("www.powerdns.com."); - vector response; - DNSPacketWriter pw(response, name, QType::A, QClass::IN, 0); + PacketBuffer response; + GenericDNSPacketWriter pw(response, name, QType::A, QClass::IN, 0); pw.getHeader()->qr = 1; pw.startRecord(name, QType::A, 3600, QClass::IN, DNSResourceRecord::ANSWER, true); pw.xfr32BitInt(0x01020304); @@ -932,7 +932,7 @@ BOOST_AUTO_TEST_CASE(removeEDNSWhenIntermediary) { pw.xfr32BitInt(0x01020304); pw.commit(); - vector newResponse; + PacketBuffer newResponse; int res = rewriteResponseWithoutEDNS(response, newResponse); BOOST_CHECK_EQUAL(res, 0); @@ -950,8 +950,8 @@ BOOST_AUTO_TEST_CASE(removeEDNSWhenIntermediary) { BOOST_AUTO_TEST_CASE(removeEDNSWhenLast) { DNSName name("www.powerdns.com."); - vector response; - DNSPacketWriter pw(response, name, QType::A, QClass::IN, 0); + PacketBuffer response; + GenericDNSPacketWriter pw(response, name, QType::A, QClass::IN, 0); pw.getHeader()->qr = 1; pw.startRecord(name, QType::A, 3600, QClass::IN, DNSResourceRecord::ANSWER, true); pw.xfr32BitInt(0x01020304); @@ -962,7 +962,7 @@ BOOST_AUTO_TEST_CASE(removeEDNSWhenLast) { pw.addOpt(512, 0, 0); pw.commit(); - vector newResponse; + PacketBuffer newResponse; int res = rewriteResponseWithoutEDNS(response, newResponse); BOOST_CHECK_EQUAL(res, 0); @@ -982,8 +982,8 @@ BOOST_AUTO_TEST_CASE(removeECSWhenOnlyOption) { DNSName name("www.powerdns.com."); ComboAddress origRemote("127.0.0.1"); - vector response; - DNSPacketWriter pw(response, name, QType::A, QClass::IN, 0); + PacketBuffer response; + GenericDNSPacketWriter pw(response, name, QType::A, QClass::IN, 0); pw.getHeader()->qr = 1; pw.startRecord(name, QType::A, 3600, QClass::IN, DNSResourceRecord::ANSWER, true); pw.xfr32BitInt(0x01020304); @@ -995,7 +995,7 @@ BOOST_AUTO_TEST_CASE(removeECSWhenOnlyOption) { EDNSSubnetOpts ecsOpts; ecsOpts.source = Netmask(origRemote, ECSSourcePrefixV4); string origECSOptionStr = makeEDNSSubnetOptsString(ecsOpts); - DNSPacketWriter::optvect_t opts; + GenericDNSPacketWriter::optvect_t opts; opts.push_back(make_pair(EDNSOptionCode::ECS, origECSOptionStr)); pw.addOpt(512, 0, 0, opts); pw.commit(); @@ -1029,8 +1029,8 @@ BOOST_AUTO_TEST_CASE(removeECSWhenFirstOption) { DNSName name("www.powerdns.com."); ComboAddress origRemote("127.0.0.1"); - vector response; - DNSPacketWriter pw(response, name, QType::A, QClass::IN, 0); + PacketBuffer response; + GenericDNSPacketWriter pw(response, name, QType::A, QClass::IN, 0); pw.getHeader()->qr = 1; pw.startRecord(name, QType::A, 3600, QClass::IN, DNSResourceRecord::ANSWER, true); pw.xfr32BitInt(0x01020304); @@ -1046,7 +1046,7 @@ BOOST_AUTO_TEST_CASE(removeECSWhenFirstOption) { cookiesOpt.client = string("deadbeef"); cookiesOpt.server = string("deadbeef"); string cookiesOptionStr = makeEDNSCookiesOptString(cookiesOpt); - DNSPacketWriter::optvect_t opts; + GenericDNSPacketWriter::optvect_t opts; opts.push_back(make_pair(EDNSOptionCode::ECS, origECSOptionStr)); opts.push_back(make_pair(EDNSOptionCode::COOKIE, cookiesOptionStr)); pw.addOpt(512, 0, 0, opts); @@ -1081,8 +1081,8 @@ BOOST_AUTO_TEST_CASE(removeECSWhenIntermediaryOption) { DNSName name("www.powerdns.com."); ComboAddress origRemote("127.0.0.1"); - vector response; - DNSPacketWriter pw(response, name, QType::A, QClass::IN, 0); + PacketBuffer response; + GenericDNSPacketWriter pw(response, name, QType::A, QClass::IN, 0); pw.getHeader()->qr = 1; pw.startRecord(name, QType::A, 3600, QClass::IN, DNSResourceRecord::ANSWER, true); pw.xfr32BitInt(0x01020304); @@ -1101,7 +1101,7 @@ BOOST_AUTO_TEST_CASE(removeECSWhenIntermediaryOption) { string cookiesOptionStr1 = makeEDNSCookiesOptString(cookiesOpt); string cookiesOptionStr2 = makeEDNSCookiesOptString(cookiesOpt); - DNSPacketWriter::optvect_t opts; + GenericDNSPacketWriter::optvect_t opts; opts.push_back(make_pair(EDNSOptionCode::COOKIE, cookiesOptionStr1)); opts.push_back(make_pair(EDNSOptionCode::ECS, origECSOptionStr)); opts.push_back(make_pair(EDNSOptionCode::COOKIE, cookiesOptionStr2)); @@ -1137,8 +1137,8 @@ BOOST_AUTO_TEST_CASE(removeECSWhenLastOption) { DNSName name("www.powerdns.com."); ComboAddress origRemote("127.0.0.1"); - vector response; - DNSPacketWriter pw(response, name, QType::A, QClass::IN, 0); + PacketBuffer response; + GenericDNSPacketWriter pw(response, name, QType::A, QClass::IN, 0); pw.getHeader()->qr = 1; pw.startRecord(name, QType::A, 3600, QClass::IN, DNSResourceRecord::ANSWER, true); pw.xfr32BitInt(0x01020304); @@ -1154,7 +1154,7 @@ BOOST_AUTO_TEST_CASE(removeECSWhenLastOption) { EDNSSubnetOpts ecsOpts; ecsOpts.source = Netmask(origRemote, ECSSourcePrefixV4); string origECSOptionStr = makeEDNSSubnetOptsString(ecsOpts); - DNSPacketWriter::optvect_t opts; + GenericDNSPacketWriter::optvect_t opts; opts.push_back(make_pair(EDNSOptionCode::COOKIE, cookiesOptionStr)); opts.push_back(make_pair(EDNSOptionCode::ECS, origECSOptionStr)); pw.addOpt(512, 0, 0, opts); @@ -1189,8 +1189,8 @@ BOOST_AUTO_TEST_CASE(rewritingWithoutECSWhenOnlyOption) { DNSName name("www.powerdns.com."); ComboAddress origRemote("127.0.0.1"); - vector response; - DNSPacketWriter pw(response, name, QType::A, QClass::IN, 0); + PacketBuffer response; + GenericDNSPacketWriter pw(response, name, QType::A, QClass::IN, 0); pw.getHeader()->qr = 1; pw.startRecord(name, QType::A, 3600, QClass::IN, DNSResourceRecord::ANSWER, true); pw.xfr32BitInt(0x01020304); @@ -1198,7 +1198,7 @@ BOOST_AUTO_TEST_CASE(rewritingWithoutECSWhenOnlyOption) { EDNSSubnetOpts ecsOpts; ecsOpts.source = Netmask(origRemote, ECSSourcePrefixV4); string origECSOptionStr = makeEDNSSubnetOptsString(ecsOpts); - DNSPacketWriter::optvect_t opts; + GenericDNSPacketWriter::optvect_t opts; opts.push_back(make_pair(EDNSOptionCode::ECS, origECSOptionStr)); pw.addOpt(512, 0, 0, opts); pw.commit(); @@ -1207,7 +1207,7 @@ BOOST_AUTO_TEST_CASE(rewritingWithoutECSWhenOnlyOption) { pw.xfr32BitInt(0x01020304); pw.commit(); - vector newResponse; + PacketBuffer newResponse; int res = rewriteResponseWithoutEDNSOption(response, EDNSOptionCode::ECS, newResponse); BOOST_CHECK_EQUAL(res, 0); @@ -1226,8 +1226,8 @@ BOOST_AUTO_TEST_CASE(rewritingWithoutECSWhenFirstOption) { DNSName name("www.powerdns.com."); ComboAddress origRemote("127.0.0.1"); - vector response; - DNSPacketWriter pw(response, name, QType::A, QClass::IN, 0); + PacketBuffer response; + GenericDNSPacketWriter pw(response, name, QType::A, QClass::IN, 0); pw.getHeader()->qr = 1; pw.startRecord(name, QType::A, 3600, QClass::IN, DNSResourceRecord::ANSWER, true); pw.xfr32BitInt(0x01020304); @@ -1239,7 +1239,7 @@ BOOST_AUTO_TEST_CASE(rewritingWithoutECSWhenFirstOption) { cookiesOpt.client = string("deadbeef"); cookiesOpt.server = string("deadbeef"); string cookiesOptionStr = makeEDNSCookiesOptString(cookiesOpt); - DNSPacketWriter::optvect_t opts; + GenericDNSPacketWriter::optvect_t opts; opts.push_back(make_pair(EDNSOptionCode::ECS, origECSOptionStr)); opts.push_back(make_pair(EDNSOptionCode::COOKIE, cookiesOptionStr)); pw.addOpt(512, 0, 0, opts); @@ -1249,7 +1249,7 @@ BOOST_AUTO_TEST_CASE(rewritingWithoutECSWhenFirstOption) { pw.xfr32BitInt(0x01020304); pw.commit(); - vector newResponse; + PacketBuffer newResponse; int res = rewriteResponseWithoutEDNSOption(response, EDNSOptionCode::ECS, newResponse); BOOST_CHECK_EQUAL(res, 0); @@ -1268,8 +1268,8 @@ BOOST_AUTO_TEST_CASE(rewritingWithoutECSWhenIntermediaryOption) { DNSName name("www.powerdns.com."); ComboAddress origRemote("127.0.0.1"); - vector response; - DNSPacketWriter pw(response, name, QType::A, QClass::IN, 0); + PacketBuffer response; + GenericDNSPacketWriter pw(response, name, QType::A, QClass::IN, 0); pw.getHeader()->qr = 1; pw.startRecord(name, QType::A, 3600, QClass::IN, DNSResourceRecord::ANSWER, true); pw.xfr32BitInt(0x01020304); @@ -1282,7 +1282,7 @@ BOOST_AUTO_TEST_CASE(rewritingWithoutECSWhenIntermediaryOption) { cookiesOpt.server = string("deadbeef"); string cookiesOptionStr1 = makeEDNSCookiesOptString(cookiesOpt); string cookiesOptionStr2 = makeEDNSCookiesOptString(cookiesOpt); - DNSPacketWriter::optvect_t opts; + GenericDNSPacketWriter::optvect_t opts; opts.push_back(make_pair(EDNSOptionCode::COOKIE, cookiesOptionStr1)); opts.push_back(make_pair(EDNSOptionCode::ECS, origECSOptionStr)); opts.push_back(make_pair(EDNSOptionCode::COOKIE, cookiesOptionStr2)); @@ -1293,7 +1293,7 @@ BOOST_AUTO_TEST_CASE(rewritingWithoutECSWhenIntermediaryOption) { pw.xfr32BitInt(0x01020304); pw.commit(); - vector newResponse; + PacketBuffer newResponse; int res = rewriteResponseWithoutEDNSOption(response, EDNSOptionCode::ECS, newResponse); BOOST_CHECK_EQUAL(res, 0); @@ -1312,8 +1312,8 @@ BOOST_AUTO_TEST_CASE(rewritingWithoutECSWhenLastOption) { DNSName name("www.powerdns.com."); ComboAddress origRemote("127.0.0.1"); - vector response; - DNSPacketWriter pw(response, name, QType::A, QClass::IN, 0); + PacketBuffer response; + GenericDNSPacketWriter pw(response, name, QType::A, QClass::IN, 0); pw.getHeader()->qr = 1; pw.startRecord(name, QType::A, 3600, QClass::IN, DNSResourceRecord::ANSWER, true); pw.xfr32BitInt(0x01020304); @@ -1325,7 +1325,7 @@ BOOST_AUTO_TEST_CASE(rewritingWithoutECSWhenLastOption) { cookiesOpt.client = string("deadbeef"); cookiesOpt.server = string("deadbeef"); string cookiesOptionStr = makeEDNSCookiesOptString(cookiesOpt); - DNSPacketWriter::optvect_t opts; + GenericDNSPacketWriter::optvect_t opts; opts.push_back(make_pair(EDNSOptionCode::COOKIE, cookiesOptionStr)); opts.push_back(make_pair(EDNSOptionCode::ECS, origECSOptionStr)); pw.addOpt(512, 0, 0, opts); @@ -1335,7 +1335,7 @@ BOOST_AUTO_TEST_CASE(rewritingWithoutECSWhenLastOption) { pw.xfr32BitInt(0x01020304); pw.commit(); - vector newResponse; + PacketBuffer newResponse; int res = rewriteResponseWithoutEDNSOption(response, EDNSOptionCode::ECS, newResponse); BOOST_CHECK_EQUAL(res, 0); @@ -1350,12 +1350,12 @@ BOOST_AUTO_TEST_CASE(rewritingWithoutECSWhenLastOption) { validateResponse(newResponse, true, 1); } -static DNSQuestion getDNSQuestion(const DNSName& qname, const uint16_t qtype, const uint16_t qclass, const ComboAddress& lc, const ComboAddress& rem, const struct timespec& realTime, vector& query) +static DNSQuestion getDNSQuestion(const DNSName& qname, const uint16_t qtype, const uint16_t qclass, const ComboAddress& lc, const ComboAddress& rem, const struct timespec& realTime, PacketBuffer& query) { return DNSQuestion(&qname, qtype, qclass, &lc, &rem, query, false, &realTime); } -static DNSQuestion turnIntoResponse(const DNSName& qname, const uint16_t qtype, const uint16_t qclass, const ComboAddress& lc, const ComboAddress& rem, const struct timespec& queryRealTime, vector& query, bool resizeBuffer=true) +static DNSQuestion turnIntoResponse(const DNSName& qname, const uint16_t qtype, const uint16_t qclass, const ComboAddress& lc, const ComboAddress& rem, const struct timespec& queryRealTime, PacketBuffer& query, bool resizeBuffer=true) { if (resizeBuffer) { query.resize(4096); @@ -1368,7 +1368,7 @@ static DNSQuestion turnIntoResponse(const DNSName& qname, const uint16_t qtype, return dq; } -static int getZ(const DNSName& qname, const uint16_t qtype, const uint16_t qclass, vector& query) +static int getZ(const DNSName& qname, const uint16_t qtype, const uint16_t qclass, PacketBuffer& query) { ComboAddress lc("127.0.0.1"); ComboAddress rem("127.0.0.1"); @@ -1393,14 +1393,14 @@ BOOST_AUTO_TEST_CASE(test_getEDNSZ) { cookiesOpt.client = string("deadbeef"); cookiesOpt.server = string("deadbeef"); string cookiesOptionStr = makeEDNSCookiesOptString(cookiesOpt); - DNSPacketWriter::optvect_t opts; + GenericDNSPacketWriter::optvect_t opts; opts.push_back(make_pair(EDNSOptionCode::COOKIE, cookiesOptionStr)); opts.push_back(make_pair(EDNSOptionCode::ECS, origECSOptionStr)); { /* no EDNS */ - vector query; - DNSPacketWriter pw(query, qname, qtype, qclass, 0); + PacketBuffer query; + GenericDNSPacketWriter pw(query, qname, qtype, qclass, 0); pw.commit(); BOOST_CHECK_EQUAL(getZ(qname, qtype, qclass, query), 0); @@ -1411,8 +1411,8 @@ BOOST_AUTO_TEST_CASE(test_getEDNSZ) { { /* truncated EDNS */ - vector query; - DNSPacketWriter pw(query, qname, qtype, qclass, 0); + PacketBuffer query; + GenericDNSPacketWriter pw(query, qname, qtype, qclass, 0); pw.addOpt(512, 0, EDNS_HEADER_FLAG_DO); pw.commit(); @@ -1425,8 +1425,8 @@ BOOST_AUTO_TEST_CASE(test_getEDNSZ) { { /* valid EDNS, no options, DO not set */ - vector query; - DNSPacketWriter pw(query, qname, qtype, qclass, 0); + PacketBuffer query; + GenericDNSPacketWriter pw(query, qname, qtype, qclass, 0); pw.addOpt(512, 0, 0); pw.commit(); @@ -1438,8 +1438,8 @@ BOOST_AUTO_TEST_CASE(test_getEDNSZ) { { /* valid EDNS, no options, DO set */ - vector query; - DNSPacketWriter pw(query, qname, qtype, qclass, 0); + PacketBuffer query; + GenericDNSPacketWriter pw(query, qname, qtype, qclass, 0); pw.addOpt(512, 0, EDNS_HEADER_FLAG_DO); pw.commit(); @@ -1451,8 +1451,8 @@ BOOST_AUTO_TEST_CASE(test_getEDNSZ) { { /* valid EDNS, options, DO not set */ - vector query; - DNSPacketWriter pw(query, qname, qtype, qclass, 0); + PacketBuffer query; + GenericDNSPacketWriter pw(query, qname, qtype, qclass, 0); pw.addOpt(512, 0, 0, opts); pw.commit(); @@ -1464,8 +1464,8 @@ BOOST_AUTO_TEST_CASE(test_getEDNSZ) { { /* valid EDNS, options, DO set */ - vector query; - DNSPacketWriter pw(query, qname, qtype, qclass, 0); + PacketBuffer query; + GenericDNSPacketWriter pw(query, qname, qtype, qclass, 0); pw.addOpt(512, 0, EDNS_HEADER_FLAG_DO, opts); pw.commit(); @@ -1491,7 +1491,7 @@ BOOST_AUTO_TEST_CASE(test_addEDNSToQueryTurnedResponse) { cookiesOpt.client = string("deadbeef"); cookiesOpt.server = string("deadbeef"); string cookiesOptionStr = makeEDNSCookiesOptString(cookiesOpt); - DNSPacketWriter::optvect_t opts; + GenericDNSPacketWriter::optvect_t opts; opts.push_back(make_pair(EDNSOptionCode::COOKIE, cookiesOptionStr)); opts.push_back(make_pair(EDNSOptionCode::ECS, origECSOptionStr)); ComboAddress lc("127.0.0.1"); @@ -1501,8 +1501,8 @@ BOOST_AUTO_TEST_CASE(test_addEDNSToQueryTurnedResponse) { { /* no EDNS */ - vector query; - DNSPacketWriter pw(query, qname, qtype, qclass, 0); + PacketBuffer query; + GenericDNSPacketWriter pw(query, qname, qtype, qclass, 0); pw.getHeader()->qr = 1; pw.getHeader()->rcode = RCode::NXDomain; pw.commit(); @@ -1516,8 +1516,8 @@ BOOST_AUTO_TEST_CASE(test_addEDNSToQueryTurnedResponse) { { /* truncated EDNS */ - vector query; - DNSPacketWriter pw(query, qname, qtype, qclass, 0); + PacketBuffer query; + GenericDNSPacketWriter pw(query, qname, qtype, qclass, 0); pw.addOpt(512, 0, EDNS_HEADER_FLAG_DO); pw.commit(); @@ -1531,8 +1531,8 @@ BOOST_AUTO_TEST_CASE(test_addEDNSToQueryTurnedResponse) { { /* valid EDNS, no options, DO not set */ - vector query; - DNSPacketWriter pw(query, qname, qtype, qclass, 0); + PacketBuffer query; + GenericDNSPacketWriter pw(query, qname, qtype, qclass, 0); pw.addOpt(512, 0, 0); pw.commit(); @@ -1545,8 +1545,8 @@ BOOST_AUTO_TEST_CASE(test_addEDNSToQueryTurnedResponse) { { /* valid EDNS, no options, DO set */ - vector query; - DNSPacketWriter pw(query, qname, qtype, qclass, 0); + PacketBuffer query; + GenericDNSPacketWriter pw(query, qname, qtype, qclass, 0); pw.addOpt(512, 0, EDNS_HEADER_FLAG_DO); pw.commit(); @@ -1559,8 +1559,8 @@ BOOST_AUTO_TEST_CASE(test_addEDNSToQueryTurnedResponse) { { /* valid EDNS, options, DO not set */ - vector query; - DNSPacketWriter pw(query, qname, qtype, qclass, 0); + PacketBuffer query; + GenericDNSPacketWriter pw(query, qname, qtype, qclass, 0); pw.addOpt(512, 0, 0, opts); pw.commit(); @@ -1573,8 +1573,8 @@ BOOST_AUTO_TEST_CASE(test_addEDNSToQueryTurnedResponse) { { /* valid EDNS, options, DO set */ - vector query; - DNSPacketWriter pw(query, qname, qtype, qclass, 0); + PacketBuffer query; + GenericDNSPacketWriter pw(query, qname, qtype, qclass, 0); pw.addOpt(512, 0, EDNS_HEADER_FLAG_DO, opts); pw.commit(); @@ -1593,7 +1593,7 @@ BOOST_AUTO_TEST_CASE(test_getEDNSOptionsStart) { EDNSSubnetOpts ecsOpts; ecsOpts.source = Netmask(ComboAddress("127.0.0.1"), ECSSourcePrefixV4); const string ecsOptionStr = makeEDNSSubnetOptsString(ecsOpts); - DNSPacketWriter::optvect_t opts; + GenericDNSPacketWriter::optvect_t opts; opts.push_back(make_pair(EDNSOptionCode::ECS, ecsOptionStr)); const ComboAddress lc("127.0.0.1"); const ComboAddress rem("127.0.0.1"); @@ -1604,8 +1604,8 @@ BOOST_AUTO_TEST_CASE(test_getEDNSOptionsStart) { { /* no EDNS */ - vector query; - DNSPacketWriter pw(query, qname, qtype, qclass, 0); + PacketBuffer query; + GenericDNSPacketWriter pw(query, qname, qtype, qclass, 0); pw.getHeader()->qr = 1; pw.getHeader()->rcode = RCode::NXDomain; pw.commit(); @@ -1623,8 +1623,8 @@ BOOST_AUTO_TEST_CASE(test_getEDNSOptionsStart) { { /* valid EDNS, no options */ - vector query; - DNSPacketWriter pw(query, qname, qtype, qclass, 0); + PacketBuffer query; + GenericDNSPacketWriter pw(query, qname, qtype, qclass, 0); pw.addOpt(512, 0, 0); pw.commit(); @@ -1643,8 +1643,8 @@ BOOST_AUTO_TEST_CASE(test_getEDNSOptionsStart) { { /* valid EDNS, options */ - vector query; - DNSPacketWriter pw(query, qname, qtype, qclass, 0); + PacketBuffer query; + GenericDNSPacketWriter pw(query, qname, qtype, qclass, 0); pw.addOpt(512, 0, 0, opts); pw.commit(); @@ -1666,7 +1666,7 @@ BOOST_AUTO_TEST_CASE(test_getEDNSOptionsStart) { BOOST_AUTO_TEST_CASE(test_isEDNSOptionInOpt) { - auto locateEDNSOption = [](const vector& query, uint16_t code, size_t* optContentStart, uint16_t* optContentLen) { + auto locateEDNSOption = [](const PacketBuffer& query, uint16_t code, size_t* optContentStart, uint16_t* optContentLen) { uint16_t optStart; size_t optLen; bool last = false; @@ -1702,7 +1702,7 @@ BOOST_AUTO_TEST_CASE(test_isEDNSOptionInOpt) { const string cookiesOptionStr = makeEDNSCookiesOptString(cookiesOpt); const size_t sizeOfCookieOption = /* option code */ 2 + /* option length */ 2 + cookiesOpt.client.size() + cookiesOpt.server.size(); /* - DNSPacketWriter::optvect_t opts; + GenericDNSPacketWriter::optvect_t opts; opts.push_back(make_pair(EDNSOptionCode::COOKIE, cookiesOptionStr)); opts.push_back(make_pair(EDNSOptionCode::ECS, ecsOptionStr)); opts.push_back(make_pair(EDNSOptionCode::COOKIE, cookiesOptionStr)); @@ -1716,8 +1716,8 @@ BOOST_AUTO_TEST_CASE(test_isEDNSOptionInOpt) { { /* no EDNS */ - vector query; - DNSPacketWriter pw(query, qname, qtype, qclass, 0); + PacketBuffer query; + GenericDNSPacketWriter pw(query, qname, qtype, qclass, 0); pw.getHeader()->qr = 1; pw.getHeader()->rcode = RCode::NXDomain; pw.commit(); @@ -1733,8 +1733,8 @@ BOOST_AUTO_TEST_CASE(test_isEDNSOptionInOpt) { { /* valid EDNS, no options */ - vector query; - DNSPacketWriter pw(query, qname, qtype, qclass, 0); + PacketBuffer query; + GenericDNSPacketWriter pw(query, qname, qtype, qclass, 0); pw.addOpt(512, 0, 0); pw.commit(); @@ -1748,9 +1748,9 @@ BOOST_AUTO_TEST_CASE(test_isEDNSOptionInOpt) { { /* valid EDNS, two cookie options but no ECS */ - vector query; - DNSPacketWriter pw(query, qname, qtype, qclass, 0); - DNSPacketWriter::optvect_t opts; + PacketBuffer query; + GenericDNSPacketWriter pw(query, qname, qtype, qclass, 0); + GenericDNSPacketWriter::optvect_t opts; opts.push_back(make_pair(EDNSOptionCode::COOKIE, cookiesOptionStr)); opts.push_back(make_pair(EDNSOptionCode::COOKIE, cookiesOptionStr)); pw.addOpt(512, 0, 0, opts); @@ -1766,9 +1766,9 @@ BOOST_AUTO_TEST_CASE(test_isEDNSOptionInOpt) { { /* valid EDNS, two ECS */ - vector query; - DNSPacketWriter pw(query, qname, qtype, qclass, 0); - DNSPacketWriter::optvect_t opts; + PacketBuffer query; + GenericDNSPacketWriter pw(query, qname, qtype, qclass, 0); + GenericDNSPacketWriter::optvect_t opts; opts.push_back(make_pair(EDNSOptionCode::ECS, ecsOptionStr)); opts.push_back(make_pair(EDNSOptionCode::ECS, ecsOptionStr)); pw.addOpt(512, 0, 0, opts); @@ -1788,9 +1788,9 @@ BOOST_AUTO_TEST_CASE(test_isEDNSOptionInOpt) { { /* valid EDNS, one ECS between two cookies */ - vector query; - DNSPacketWriter pw(query, qname, qtype, qclass, 0); - DNSPacketWriter::optvect_t opts; + PacketBuffer query; + GenericDNSPacketWriter pw(query, qname, qtype, qclass, 0); + GenericDNSPacketWriter::optvect_t opts; opts.push_back(make_pair(EDNSOptionCode::COOKIE, cookiesOptionStr)); opts.push_back(make_pair(EDNSOptionCode::ECS, ecsOptionStr)); opts.push_back(make_pair(EDNSOptionCode::COOKIE, cookiesOptionStr)); @@ -1811,9 +1811,9 @@ BOOST_AUTO_TEST_CASE(test_isEDNSOptionInOpt) { { /* valid EDNS, one 65002 after an ECS */ - vector query; - DNSPacketWriter pw(query, qname, qtype, qclass, 0); - DNSPacketWriter::optvect_t opts; + PacketBuffer query; + GenericDNSPacketWriter pw(query, qname, qtype, qclass, 0); + GenericDNSPacketWriter::optvect_t opts; opts.push_back(make_pair(EDNSOptionCode::ECS, ecsOptionStr)); opts.push_back(make_pair(65535, cookiesOptionStr)); pw.addOpt(512, 0, 0, opts); @@ -1838,11 +1838,11 @@ BOOST_AUTO_TEST_CASE(test_setNegativeAndAdditionalSOA) { ComboAddress remote; DNSName name("www.powerdns.com."); - vector query; - vector queryWithEDNS; - DNSPacketWriter pw(query, name, QType::A, QClass::IN, 0); + PacketBuffer query; + PacketBuffer queryWithEDNS; + GenericDNSPacketWriter pw(query, name, QType::A, QClass::IN, 0); pw.getHeader()->rd = 1; - DNSPacketWriter pwEDNS(queryWithEDNS, name, QType::A, QClass::IN, 0); + GenericDNSPacketWriter pwEDNS(queryWithEDNS, name, QType::A, QClass::IN, 0); pwEDNS.getHeader()->rd = 1; pwEDNS.addOpt(1232, 0, 0); pwEDNS.commit(); @@ -1960,8 +1960,8 @@ BOOST_AUTO_TEST_CASE(getEDNSOptionsWithoutEDNS) { { /* no EDNS and no other additional record */ - vector query; - DNSPacketWriter pw(query, name, QType::A, QClass::IN, 0); + PacketBuffer query; + GenericDNSPacketWriter pw(query, name, QType::A, QClass::IN, 0); pw.getHeader()->rd = 1; pw.commit(); @@ -1979,8 +1979,8 @@ BOOST_AUTO_TEST_CASE(getEDNSOptionsWithoutEDNS) { { /* nothing in additional (so no EDNS) but a record in ANSWER */ - vector query; - DNSPacketWriter pw(query, name, QType::A, QClass::IN, 0); + PacketBuffer query; + GenericDNSPacketWriter pw(query, name, QType::A, QClass::IN, 0); pw.getHeader()->rd = 1; pw.startRecord(name, QType::A, 60, QClass::IN, DNSResourceRecord::ANSWER); pw.xfrIP(v4.sin4.sin_addr.s_addr); @@ -2000,8 +2000,8 @@ BOOST_AUTO_TEST_CASE(getEDNSOptionsWithoutEDNS) { { /* nothing in additional (so no EDNS) but a record in AUTHORITY */ - vector query; - DNSPacketWriter pw(query, name, QType::A, QClass::IN, 0); + PacketBuffer query; + GenericDNSPacketWriter pw(query, name, QType::A, QClass::IN, 0); pw.getHeader()->rd = 1; pw.startRecord(name, QType::A, 60, QClass::IN, DNSResourceRecord::AUTHORITY); pw.xfrIP(v4.sin4.sin_addr.s_addr); diff --git a/pdns/test-dnsdistpacketcache_cc.cc b/pdns/test-dnsdistpacketcache_cc.cc index 428e12cb98cc..4acd98a75d2d 100644 --- a/pdns/test-dnsdistpacketcache_cc.cc +++ b/pdns/test-dnsdistpacketcache_cc.cc @@ -31,12 +31,12 @@ BOOST_AUTO_TEST_CASE(test_PacketCacheSimple) { DNSName a=DNSName(std::to_string(counter))+DNSName(" hello"); BOOST_CHECK_EQUAL(DNSName(a.toString()), a); - vector query; - DNSPacketWriter pwQ(query, a, QType::A, QClass::IN, 0); + PacketBuffer query; + GenericDNSPacketWriter pwQ(query, a, QType::A, QClass::IN, 0); pwQ.getHeader()->rd = 1; - vector response; - DNSPacketWriter pwR(response, a, QType::A, QClass::IN, 0); + PacketBuffer response; + GenericDNSPacketWriter pwR(response, a, QType::A, QClass::IN, 0); pwR.getHeader()->rd = 1; pwR.getHeader()->ra = 1; pwR.getHeader()->qr = 1; @@ -73,8 +73,8 @@ BOOST_AUTO_TEST_CASE(test_PacketCacheSimple) { size_t delcounter=0; for(delcounter=0; delcounter < counter/1000; ++delcounter) { DNSName a=DNSName(std::to_string(delcounter))+DNSName(" hello"); - vector query; - DNSPacketWriter pwQ(query, a, QType::A, QClass::IN, 0); + PacketBuffer query; + GenericDNSPacketWriter pwQ(query, a, QType::A, QClass::IN, 0); pwQ.getHeader()->rd = 1; uint32_t key = 0; boost::optional subnet; @@ -93,8 +93,8 @@ BOOST_AUTO_TEST_CASE(test_PacketCacheSimple) { size_t expected=counter-skipped-deleted; for(; delcounter < counter; ++delcounter) { DNSName a(DNSName(std::to_string(delcounter))+DNSName(" hello")); - vector query; - DNSPacketWriter pwQ(query, a, QType::A, QClass::IN, 0); + PacketBuffer query; + GenericDNSPacketWriter pwQ(query, a, QType::A, QClass::IN, 0); pwQ.getHeader()->rd = 1; uint32_t key = 0; boost::optional subnet; @@ -131,12 +131,12 @@ BOOST_AUTO_TEST_CASE(test_PacketCacheServFailTTL) { DNSName a = DNSName("servfail"); BOOST_CHECK_EQUAL(DNSName(a.toString()), a); - vector query; - DNSPacketWriter pwQ(query, a, QType::A, QClass::IN, 0); + PacketBuffer query; + GenericDNSPacketWriter pwQ(query, a, QType::A, QClass::IN, 0); pwQ.getHeader()->rd = 1; - vector response; - DNSPacketWriter pwR(response, a, QType::A, QClass::IN, 0); + PacketBuffer response; + GenericDNSPacketWriter pwR(response, a, QType::A, QClass::IN, 0); pwR.getHeader()->rd = 1; pwR.getHeader()->ra = 0; pwR.getHeader()->qr = 1; @@ -180,12 +180,12 @@ BOOST_AUTO_TEST_CASE(test_PacketCacheNoDataTTL) { bool dnssecOK = false; try { DNSName name("nodata"); - vector query; - DNSPacketWriter pwQ(query, name, QType::A, QClass::IN, 0); + PacketBuffer query; + GenericDNSPacketWriter pwQ(query, name, QType::A, QClass::IN, 0); pwQ.getHeader()->rd = 1; - vector response; - DNSPacketWriter pwR(response, name, QType::A, QClass::IN, 0); + PacketBuffer response; + GenericDNSPacketWriter pwR(response, name, QType::A, QClass::IN, 0); pwR.getHeader()->rd = 1; pwR.getHeader()->ra = 0; pwR.getHeader()->qr = 1; @@ -232,12 +232,12 @@ BOOST_AUTO_TEST_CASE(test_PacketCacheNXDomainTTL) { bool dnssecOK = false; try { DNSName name("nxdomain"); - vector query; - DNSPacketWriter pwQ(query, name, QType::A, QClass::IN, 0); + PacketBuffer query; + GenericDNSPacketWriter pwQ(query, name, QType::A, QClass::IN, 0); pwQ.getHeader()->rd = 1; - vector response; - DNSPacketWriter pwR(response, name, QType::A, QClass::IN, 0); + PacketBuffer response; + GenericDNSPacketWriter pwR(response, name, QType::A, QClass::IN, 0); pwR.getHeader()->rd = 1; pwR.getHeader()->ra = 0; pwR.getHeader()->qr = 1; @@ -284,12 +284,12 @@ static void threadMangler(unsigned int offset) bool dnssecOK = false; for(unsigned int counter=0; counter < 100000; ++counter) { DNSName a=DNSName("hello ")+DNSName(std::to_string(counter+offset)); - vector query; - DNSPacketWriter pwQ(query, a, QType::A, QClass::IN, 0); + PacketBuffer query; + GenericDNSPacketWriter pwQ(query, a, QType::A, QClass::IN, 0); pwQ.getHeader()->rd = 1; - vector response; - DNSPacketWriter pwR(response, a, QType::A, QClass::IN, 0); + PacketBuffer response; + GenericDNSPacketWriter pwR(response, a, QType::A, QClass::IN, 0); pwR.getHeader()->rd = 1; pwR.getHeader()->ra = 1; pwR.getHeader()->qr = 1; @@ -325,8 +325,8 @@ static void threadReader(unsigned int offset) ComboAddress remote; for(unsigned int counter=0; counter < 100000; ++counter) { DNSName a=DNSName("hello ")+DNSName(std::to_string(counter+offset)); - vector query; - DNSPacketWriter pwQ(query, a, QType::A, QClass::IN, 0); + PacketBuffer query; + GenericDNSPacketWriter pwQ(query, a, QType::A, QClass::IN, 0); pwQ.getHeader()->rd = 1; uint32_t key = 0; @@ -393,11 +393,11 @@ BOOST_AUTO_TEST_CASE(test_PCCollision) { /* lookup for a query with a first ECS value, insert a corresponding response */ { - vector query; - DNSPacketWriter pwQ(query, qname, qtype, QClass::IN, 0); + PacketBuffer query; + GenericDNSPacketWriter pwQ(query, qname, qtype, QClass::IN, 0); pwQ.getHeader()->rd = 1; pwQ.getHeader()->id = qid; - DNSPacketWriter::optvect_t ednsOptions; + GenericDNSPacketWriter::optvect_t ednsOptions; EDNSSubnetOpts opt; opt.source = Netmask("10.0.59.220/32"); ednsOptions.push_back(std::make_pair(EDNSOptionCode::ECS, makeEDNSSubnetOptsString(opt))); @@ -413,8 +413,8 @@ BOOST_AUTO_TEST_CASE(test_PCCollision) { BOOST_REQUIRE(subnetOut); BOOST_CHECK_EQUAL(subnetOut->toString(), opt.source.toString()); - vector response; - DNSPacketWriter pwR(response, qname, qtype, QClass::IN, 0); + PacketBuffer response; + GenericDNSPacketWriter pwR(response, qname, qtype, QClass::IN, 0); pwR.getHeader()->rd = 1; pwR.getHeader()->id = qid; pwR.startRecord(qname, qtype, 100, QClass::IN, DNSResourceRecord::ANSWER); @@ -436,11 +436,11 @@ BOOST_AUTO_TEST_CASE(test_PCCollision) { /* now lookup for the same query with a different ECS value, we should get the same key (collision) but no match */ { - vector query; - DNSPacketWriter pwQ(query, qname, qtype, QClass::IN, 0); + PacketBuffer query; + GenericDNSPacketWriter pwQ(query, qname, qtype, QClass::IN, 0); pwQ.getHeader()->rd = 1; pwQ.getHeader()->id = qid; - DNSPacketWriter::optvect_t ednsOptions; + GenericDNSPacketWriter::optvect_t ednsOptions; EDNSSubnetOpts opt; opt.source = Netmask("10.0.167.48/32"); ednsOptions.push_back(std::make_pair(EDNSOptionCode::ECS, makeEDNSSubnetOptsString(opt))); @@ -463,7 +463,7 @@ BOOST_AUTO_TEST_CASE(test_PCCollision) { /* to be able to compute a new collision if the packet cache hashing code is updated */ { DNSDistPacketCache pc(10000); - DNSPacketWriter::optvect_t ednsOptions; + GenericDNSPacketWriter::optvect_t ednsOptions; EDNSSubnetOpts opt; std::map colMap; size_t collisions = 0; @@ -473,8 +473,8 @@ BOOST_AUTO_TEST_CASE(test_PCCollision) { for (size_t idxA = 0; idxA < 256; idxA++) { for (size_t idxB = 0; idxB < 256; idxB++) { for (size_t idxC = 0; idxC < 256; idxC++) { - vector secondQuery; - DNSPacketWriter pwFQ(secondQuery, qname, QType::AAAA, QClass::IN, 0); + PacketBuffer secondQuery; + GenericDNSPacketWriter pwFQ(secondQuery, qname, QType::AAAA, QClass::IN, 0); pwFQ.getHeader()->rd = 1; pwFQ.getHeader()->qr = false; pwFQ.getHeader()->id = 0x42; @@ -516,8 +516,8 @@ BOOST_AUTO_TEST_CASE(test_PCDNSSECCollision) { insert a corresponding response with DO set, check that it doesn't match without DO, but does with it */ { - vector query; - DNSPacketWriter pwQ(query, qname, qtype, QClass::IN, 0); + PacketBuffer query; + GenericDNSPacketWriter pwQ(query, qname, qtype, QClass::IN, 0); pwQ.getHeader()->rd = 1; pwQ.getHeader()->id = qid; pwQ.addOpt(512, 0, EDNS_HEADER_FLAG_DO); @@ -530,8 +530,8 @@ BOOST_AUTO_TEST_CASE(test_PCDNSSECCollision) { bool found = PC.get(dq, 0, &key, subnetOut, true); BOOST_CHECK_EQUAL(found, false); - vector response; - DNSPacketWriter pwR(response, qname, qtype, QClass::IN, 0); + PacketBuffer response; + GenericDNSPacketWriter pwR(response, qname, qtype, QClass::IN, 0); pwR.getHeader()->rd = 1; pwR.getHeader()->id = qid; pwR.startRecord(qname, qtype, 100, QClass::IN, DNSResourceRecord::ANSWER);