From ac10822ef5a9d3f917fd42ac2b3e913c250c8b5a Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 20 Oct 2020 11:11:49 +0200 Subject: [PATCH] Save two pieces of protbuf string in the cache to allow for mod of the response object. TODO: NOD stuff, tagging, checking of the taggedOnly flag --- pdns/pdns_recursor.cc | 55 ++++++-------- pdns/protozero.cc | 12 +-- pdns/protozero.hh | 129 +++++++++++++++++---------------- pdns/recpacketcache.cc | 39 ++++------ pdns/recpacketcache.hh | 17 +++-- pdns/test-recpacketcache_cc.cc | 18 ++--- 6 files changed, 133 insertions(+), 137 deletions(-) diff --git a/pdns/pdns_recursor.cc b/pdns/pdns_recursor.cc index 6b81c3e2de..2146465599 100644 --- a/pdns/pdns_recursor.cc +++ b/pdns/pdns_recursor.cc @@ -885,8 +885,8 @@ static void protobufLogQuery(uint8_t maskV4, uint8_t maskV6, const boost::uuids: Netmask requestorNM(remote, remote.sin4.sin_family == AF_INET ? maskV4 : maskV6); ComboAddress requestor = requestorNM.getMaskedNetwork(); requestor.setPort(remote.getPort()); - - pdns::ProtoZero::Message m{128}; // guess at size + + pdns::ProtoZero::Message m{128, std::string::size_type(policyTags.empty() ? 0 : 64)}; // XXX guesses at sizes m.request(uniqueId, requestor, local, qname, qtype, qclass, id, tcp, len); m.setServerIdentity(SyncRes::s_serverID); m.setEDNSSubnet(ednssubnet, ednssubnet.isIPv4() ? maskV4 : maskV6); @@ -895,25 +895,24 @@ static void protobufLogQuery(uint8_t maskV4, uint8_t maskV6, const boost::uuids: m.setDeviceName(deviceName); if (!policyTags.empty()) { - m.startResponse(); m.setPolicyTags(policyTags); - m.finishResponse(); } + std::string msg(m.movebuf()); for (auto& server : *t_protobufServers) { - server->queueData(m.getbuf()); + server->queueData(msg); } } -static void protobufLogResponse(const pdns::ProtoZero::Message& message) +static void protobufLogResponse(pdns::ProtoZero::Message& message) { if (!t_protobufServers) { return; } - string data = message.getbuf(); + std::string msg(message.movebuf()); for (auto& server : *t_protobufServers) { - server->queueData(data); + server->queueData(msg); } } #endif @@ -1406,15 +1405,14 @@ static void startDoResolve(void *p) // Used to tell syncres later on if we should apply NSDNAME and NSIP RPZ triggers for this query bool wantsRPZ(true); std::unique_ptr pbMessage; - std::string::size_type pbUnmutablePart; // defines the (first) part of the protobuf message that is equal for everyone + RecursorPacketCache::OptPBData pbDataForCache; #ifdef HAVE_PROTOBUF if (checkProtobufExport(luaconfsLocal)) { - pbMessage = make_unique(128); // guess at size + pbMessage = make_unique(128, 128); // XXX guess at sizes pbMessage->response(dc->d_mdp.d_qname, dc->d_mdp.d_qtype, dc->d_mdp.d_qclass); pbMessage->setServerIdentity(SyncRes::s_serverID); // RRSets added below - pbMessage->startResponse(); } #endif /* HAVE_PROTOBUF */ @@ -1871,21 +1869,20 @@ static void startDoResolve(void *p) } // XXX if (nod) pbMessage->setPolicyTags(dc->d_policyTags); - pbMessage->finishResponse(); pbMessage->setInBytes(packet.size()); - // Done with embedded DNSResponse object and done with unmutable part. - pbUnmutablePart = pbMessage->getbuf().length(); + pbDataForCache = boost::make_optional(RecursorPacketCache::PBData{ + pbMessage->getmsgbuf(), + pbMessage->getrspbuf(), + !appliedPolicy.getName().empty() || !dc->d_policyTags.empty()}); - // Below arte the fields that are not stored in the packet cache and will be appended here and on a cache hit - pbMessage->startResponse(); + // Below are the fields that are not stored in the packet cache and will be appended here and on a cache hit if (g_useKernelTimestamp && dc->d_kernelTimestamp.tv_sec) { pbMessage->setQueryTime(dc->d_kernelTimestamp.tv_sec, dc->d_kernelTimestamp.tv_usec); } else { pbMessage->setQueryTime(dc->d_now.tv_sec, dc->d_now.tv_usec); } - pbMessage->finishResponse(); pbMessage->setMessageIdentity(dc->d_uuid); pbMessage->setSocketFamily(dc->d_source.sin4.sin_family); pbMessage->setSocketProtocol(dc->d_tcp); @@ -1895,7 +1892,6 @@ static void startDoResolve(void *p) pbMessage->setTo(dc->d_destination); pbMessage->setId(dc->d_mdp.d_header.id); - // Th exact semantics of timeSec/timeUsec vs queryTimeSec/queryTimeUsec are unclear to me ATM pbMessage->setTime(); pbMessage->setEDNSSubnet(dc->d_ednssubnet.source, dc->d_ednssubnet.source.isIPv4() ? luaconfsLocal->protobufMaskV4 : luaconfsLocal->protobufMaskV6); pbMessage->setRequestorId(dq.requestorId); @@ -1955,7 +1951,7 @@ static void startDoResolve(void *p) pw.getHeader()->rcode == RCode::ServFail ? SyncRes::s_packetcacheservfailttl : min(minTTL,SyncRes::s_packetcachettl), dq.validationState, - pbMessage.get(), pbUnmutablePart); + pbDataForCache); } // else cerr<<"Not putting in packet cache: "<protobufExportConfig.taggedOnly && policyTags.empty())) { @@ -2706,10 +2702,10 @@ static string* doProcessUDPQuestion(const std::string& question, const ComboAddr as cacheable we would cache it with a wrong tag, so better safe than sorry. */ vState valState; if (qnameParsed) { - cacheHit = !SyncRes::s_nopacketcache && t_packetCache->getResponsePacket(ctag, question, qname, qtype, qclass, g_now.tv_sec, &response, &age, &valState, &qhash, &pbString); + cacheHit = !SyncRes::s_nopacketcache && t_packetCache->getResponsePacket(ctag, question, qname, qtype, qclass, g_now.tv_sec, &response, &age, &valState, &qhash, &pbData); } else { - cacheHit = !SyncRes::s_nopacketcache && t_packetCache->getResponsePacket(ctag, question, qname, &qtype, &qclass, g_now.tv_sec, &response, &age, &valState, &qhash, &pbString); + cacheHit = !SyncRes::s_nopacketcache && t_packetCache->getResponsePacket(ctag, question, qname, &qtype, &qclass, g_now.tv_sec, &response, &age, &valState, &qhash, &pbData); } if (cacheHit) { @@ -2721,17 +2717,17 @@ static string* doProcessUDPQuestion(const std::string& question, const ComboAddr } #ifdef HAVE_PROTOBUF - if(t_protobufServers && logResponse /* && !(luaconfsLocal->protobufExportConfig.taggedOnly && pbMessage->appliedPolicyIsSet() && pbMessage->policyTagsAreSet()) */) { + if(t_protobufServers && logResponse && !(luaconfsLocal->protobufExportConfig.taggedOnly && pbData && !pbData->d_tagged)) { // XXX std::unique_ptr pbMessage; - if (pbString != nullptr) { + if (pbData) { // We take the inmutable string form the cache an are appending a few values - pbMessage = make_unique(*pbString, 128); // The extra bytes we are going to add + pbMessage = make_unique(pbData->d_message, pbData->d_response, 128, 128); // The extra bytes we are going to add } else { - pbMessage = make_unique(128); + pbMessage = make_unique(128, 128); pbMessage->setType(2); // Response pbMessage->setServerIdentity(SyncRes::s_serverID); } - //cerr << "from cache: " << pbMessage->getbuf().length() << endl; + Netmask requestorNM(source, source.sin4.sin_family == AF_INET ? luaconfsLocal->protobufMaskV4 : luaconfsLocal->protobufMaskV6); ComboAddress requestor = requestorNM.getMaskedNetwork(); pbMessage->setMessageIdentity(uniqueId); @@ -2739,23 +2735,20 @@ static string* doProcessUDPQuestion(const std::string& question, const ComboAddr pbMessage->setTo(destination); pbMessage->setSocketProtocol(false); pbMessage->setId(dh->id); - // Exact semantics of the various timestamps are unclear to me ATM + pbMessage->setTime(); - pbMessage->startResponse(); if (g_useKernelTimestamp && tv.tv_sec) { pbMessage->setQueryTime(tv.tv_sec, tv.tv_usec); } else { pbMessage->setQueryTime(g_now.tv_sec, g_now.tv_usec); } - pbMessage->finishResponse(); pbMessage->setEDNSSubnet(ednssubnet.source, ednssubnet.source.isIPv4() ? luaconfsLocal->protobufMaskV4 : luaconfsLocal->protobufMaskV6); pbMessage->setRequestorId(requestorId); pbMessage->setDeviceId(deviceId); pbMessage->setDeviceName(deviceName); pbMessage->setFromPort(source.getPort()); pbMessage->setToPort(destination.getPort()); - //cerr << "affter adding: " << pbMessage->getbuf().length() << endl; protobufLogResponse(*pbMessage); } #endif /* HAVE_PROTOBUF */ diff --git a/pdns/protozero.cc b/pdns/protozero.cc index 2be7f8736c..43842e2274 100644 --- a/pdns/protozero.cc +++ b/pdns/protozero.cc @@ -27,10 +27,10 @@ void pdns::ProtoZero::Message::encodeComboAddress(const protozero::pbf_tag_type type, const ComboAddress& ca) { if (ca.sin4.sin_family == AF_INET) { - d_pbf.add_bytes(type, reinterpret_cast(&ca.sin4.sin_addr.s_addr), sizeof(ca.sin4.sin_addr.s_addr)); + d_message.add_bytes(type, reinterpret_cast(&ca.sin4.sin_addr.s_addr), sizeof(ca.sin4.sin_addr.s_addr)); } else if (ca.sin4.sin_family == AF_INET6) { - d_pbf.add_bytes(type, reinterpret_cast(&ca.sin6.sin6_addr.s6_addr), sizeof(ca.sin6.sin6_addr.s6_addr)); + d_message.add_bytes(type, reinterpret_cast(&ca.sin6.sin6_addr.s6_addr), sizeof(ca.sin6.sin6_addr.s6_addr)); } } @@ -40,10 +40,10 @@ void pdns::ProtoZero::Message::encodeNetmask(const protozero::pbf_tag_type type, ComboAddress ca(subnet.getNetwork()); ca.truncate(mask); if (ca.sin4.sin_family == AF_INET) { - d_pbf.add_bytes(type, reinterpret_cast(&ca.sin4.sin_addr.s_addr), sizeof(ca.sin4.sin_addr.s_addr)); + d_message.add_bytes(type, reinterpret_cast(&ca.sin4.sin_addr.s_addr), sizeof(ca.sin4.sin_addr.s_addr)); } else if (ca.sin4.sin_family == AF_INET6) { - d_pbf.add_bytes(type, reinterpret_cast(&ca.sin6.sin6_addr.s6_addr), sizeof(ca.sin6.sin6_addr.s6_addr)); + d_message.add_bytes(type, reinterpret_cast(&ca.sin6.sin6_addr.s6_addr), sizeof(ca.sin6.sin6_addr.s6_addr)); } } } @@ -94,9 +94,9 @@ void pdns::ProtoZero::Message::addRR(const DNSRecord& record, const std::set(uniqueId.begin()), uniqueId.size()); + d_message.add_bytes(2, reinterpret_cast(uniqueId.begin()), uniqueId.size()); } void setServerIdentity(const std::string& serverIdentity) { - d_pbf.add_bytes(3, serverIdentity.data(), serverIdentity.length()); + d_message.add_bytes(3, serverIdentity.data(), serverIdentity.length()); } void setSocketFamily(int family) { - d_pbf.add_enum(4, family == AF_INET ? 1 : 2); + d_message.add_enum(4, family == AF_INET ? 1 : 2); } void setSocketProtocol(bool tcp) { - d_pbf.add_enum(5, tcp ? 2 : 1); + d_message.add_enum(5, tcp ? 2 : 1); } void setFrom(const ComboAddress& ca) { @@ -88,7 +109,7 @@ namespace pdns { void setInBytes(uint64_t len) { if (len) { - d_pbf.add_uint64(8, len); + d_message.add_uint64(8, len); } } void setTime() @@ -96,18 +117,18 @@ namespace pdns { struct timespec ts; gettime(&ts, true); // timeSec - d_pbf.add_uint32(9, ts.tv_sec); + d_message.add_uint32(9, ts.tv_sec); // timeUsec - d_pbf.add_uint32(10, ts.tv_nsec / 1000); + d_message.add_uint32(10, ts.tv_nsec / 1000); } void setId(uint16_t id) { - d_pbf.add_uint32(11, ntohs(id)); + d_message.add_uint32(11, ntohs(id)); } void setQuestion(const DNSName& qname, uint16_t qtype, uint16_t qclass) { - protozero::pbf_writer pbf_question{d_pbf, 12}; - encodeDNSName(pbf_question, d_buffer, 1, qname); + protozero::pbf_writer pbf_question{d_message, 12}; + encodeDNSName(pbf_question, d_msgbuf, 1, qname); pbf_question.add_uint32(2, qtype); pbf_question.add_uint32(3, qclass); } @@ -117,57 +138,46 @@ namespace pdns { } void setRequestorId(const std::string& req) { - if (true || !req.empty()) { - d_pbf.add_string(15, req); + if (!req.empty()) { + d_message.add_string(15, req); } } void setInitialRequesId(const std::string& id) { if (!id.empty()) { - d_pbf.add_string(16, id); + d_message.add_string(16, id); } } void setDeviceId(const std::string& id) { - if (true || !id.empty()) { - d_pbf.add_string(17, id); + if (!id.empty()) { + d_message.add_string(17, id); } } void setNewlyObservedDomain(bool nod) { - d_pbf.add_bool(18, nod); + d_message.add_bool(18, nod); } void setDeviceName(const std::string& name) { - if (true || !name.empty()) { - d_pbf.add_string(19, name); + if (!name.empty()) { + d_message.add_string(19, name); } } void setFromPort(in_port_t port) { - d_pbf.add_uint32(20, port); + d_message.add_uint32(20, port); } void setToPort(in_port_t port) { - d_pbf.add_uint32(21, port); + d_message.add_uint32(21, port); } // DNSResponse related fields below - void startResponse() - { - if (d_response != nullptr) { - throw new runtime_error("response already inited"); - } - d_response = new protozero::pbf_writer(d_pbf, 13); - } - void finishResponse() - { - delete d_response; - d_response = nullptr; - } + void setResponseCode(uint8_t rcode) { - d_response->add_uint32(1, rcode); + d_response.add_uint32(1, rcode); } #ifdef NOD_ENABLED void addRR(const DNSRecord& record, const std::set& exportTypes, bool udr); @@ -179,16 +189,12 @@ namespace pdns { } void setAppliedPolicy(const std::string& policy) { - d_response->add_string(3, policy); - } - bool appliedPolicyIsSet() const - { - return false; + d_response.add_string(3, policy); } void setPolicyTags(const std::unordered_set& tags) { for (const auto& tag : tags) { - d_response->add_string(4, tag); + d_response.add_string(4, tag); } } void addPolicyTag(const string& tag) @@ -197,14 +203,10 @@ namespace pdns { void removePolicyTag(const string& tag) { } - bool policyTagsAreSet() const - { - return false; - } void setQueryTime(uint32_t sec, uint32_t usec) { - d_response->add_uint32(5, sec); - d_response->add_uint32(6, usec); + d_response.add_uint32(5, sec); + d_response.add_uint32(6, usec); } void setAppliedPolicyType(const DNSFilterEngine::PolicyType type) { @@ -232,21 +234,22 @@ namespace pdns { default: throw std::runtime_error("Unsupported protobuf policy type"); } - d_response->add_uint32(7, p); + d_response.add_uint32(7, p); } void setAppliedPolicyTrigger(const DNSName& trigger) { - encodeDNSName(*d_response, d_buffer, 8, trigger); + encodeDNSName(d_response, d_rspbuf, 8, trigger); } void setAppliedPolicyHit(const std::string& hit) { - d_response->add_string(9, hit); + d_response.add_string(9, hit); } private: - std::string d_buffer; - protozero::pbf_writer d_pbf; - protozero::pbf_writer *d_response{nullptr}; + std::string d_msgbuf; + std::string d_rspbuf; + protozero::pbf_writer d_message; + protozero::pbf_writer d_response; }; }; }; diff --git a/pdns/recpacketcache.cc b/pdns/recpacketcache.cc index 03758d1392..94c979c50f 100644 --- a/pdns/recpacketcache.cc +++ b/pdns/recpacketcache.cc @@ -50,7 +50,7 @@ bool RecursorPacketCache::qrMatch(const packetCache_t::index::type::ite return queryMatches(iter->d_query, queryPacket, qname, optionsToSkip); } -bool RecursorPacketCache::checkResponseMatches(std::pair::type::iterator, packetCache_t::index::type::iterator> range, const std::string& queryPacket, const DNSName& qname, uint16_t qtype, uint16_t qclass, time_t now, std::string* responsePacket, uint32_t* age, vState* valState, std::string** protobufMessage) +bool RecursorPacketCache::checkResponseMatches(std::pair::type::iterator, packetCache_t::index::type::iterator> range, const std::string& queryPacket, const DNSName& qname, uint16_t qtype, uint16_t qclass, time_t now, std::string* responsePacket, uint32_t* age, vState* valState, OptPBData* pbdata) { for(auto iter = range.first ; iter != range.second ; ++iter) { // the possibility is VERY real that we get hits that are not right - birthday paradox @@ -72,12 +72,11 @@ bool RecursorPacketCache::checkResponseMatches(std::pair(d_packetCache, iter); #ifdef HAVE_PROTOBUF - if (protobufMessage) { - if (iter->d_protobufMessage) { - *protobufMessage = &*iter->d_protobufMessage; - } - else { - *protobufMessage = nullptr; + if (pbdata != nullptr) { + if (iter->d_pbdata) { + *pbdata = iter->d_pbdata; + } else { + *pbdata = boost::none; } } #endif @@ -110,7 +109,7 @@ bool RecursorPacketCache::getResponsePacket(unsigned int tag, const std::string& } bool RecursorPacketCache::getResponsePacket(unsigned int tag, const std::string& queryPacket, const DNSName& qname, uint16_t qtype, uint16_t qclass, time_t now, - std::string* responsePacket, uint32_t* age, vState* valState, uint32_t* qhash, std::string** protobufMessage) + std::string* responsePacket, uint32_t* age, vState* valState, uint32_t* qhash, OptPBData* pbdata) { *qhash = canHashPacket(queryPacket, true); const auto& idx = d_packetCache.get(); @@ -121,11 +120,11 @@ bool RecursorPacketCache::getResponsePacket(unsigned int tag, const std::string& return false; } - return checkResponseMatches(range, queryPacket, qname, qtype, qclass, now, responsePacket, age, valState, protobufMessage); + return checkResponseMatches(range, queryPacket, qname, qtype, qclass, now, responsePacket, age, valState, pbdata); } bool RecursorPacketCache::getResponsePacket(unsigned int tag, const std::string& queryPacket, DNSName& qname, uint16_t* qtype, uint16_t* qclass, time_t now, - std::string* responsePacket, uint32_t* age, vState* valState, uint32_t* qhash, std::string** protobufMessage) + std::string* responsePacket, uint32_t* age, vState* valState, uint32_t* qhash, OptPBData *pbdata) { *qhash = canHashPacket(queryPacket, true); const auto& idx = d_packetCache.get(); @@ -138,11 +137,11 @@ bool RecursorPacketCache::getResponsePacket(unsigned int tag, const std::string& qname = DNSName(queryPacket.c_str(), queryPacket.length(), sizeof(dnsheader), false, qtype, qclass, 0); - return checkResponseMatches(range, queryPacket, qname, *qtype, *qclass, now, responsePacket, age, valState, protobufMessage); + return checkResponseMatches(range, queryPacket, qname, *qtype, *qclass, now, responsePacket, age, valState, pbdata); } -void RecursorPacketCache::insertResponsePacket(unsigned int tag, uint32_t qhash, std::string&& query, const DNSName& qname, uint16_t qtype, uint16_t qclass, std::string&& responsePacket, time_t now, uint32_t ttl, const vState& valState, pdns::ProtoZero::Message* protobufMessage, std::string::size_type pbUnmutablePart) +void RecursorPacketCache::insertResponsePacket(unsigned int tag, uint32_t qhash, std::string&& query, const DNSName& qname, uint16_t qtype, uint16_t qclass, std::string&& responsePacket, time_t now, uint32_t ttl, const vState& valState, const OptPBData& pbdata) { auto& idx = d_packetCache.get(); auto range = idx.equal_range(tie(tag,qhash)); @@ -160,11 +159,8 @@ void RecursorPacketCache::insertResponsePacket(unsigned int tag, uint32_t qhash, iter->d_creation = now; iter->d_vstate = valState; #ifdef HAVE_PROTOBUF - if (protobufMessage) { - std::string s(protobufMessage->movebuf()); - s.resize(pbUnmutablePart); - s.shrink_to_fit(); - iter->d_protobufMessage = boost::optional(s); + if (pbdata) { + iter->d_pbdata = *pbdata; } #endif @@ -181,11 +177,8 @@ void RecursorPacketCache::insertResponsePacket(unsigned int tag, uint32_t qhash, e.d_tag = tag; e.d_vstate = valState; #ifdef HAVE_PROTOBUF - if (protobufMessage) { - std::string s(protobufMessage->movebuf()); - s.resize(pbUnmutablePart); - s.shrink_to_fit(); - e.d_protobufMessage = boost::optional(s); + if (pbdata) { + e.d_pbdata = *pbdata; } #endif d_packetCache.insert(e); @@ -225,7 +218,7 @@ uint64_t RecursorPacketCache::doDump(int fd) for(auto i=sidx.cbegin(); i != sidx.cend(); ++i) { count++; try { - fprintf(fp.get(), "%s %" PRId64 " %s ; tag %d pb %zu\n", i->d_name.toString().c_str(), static_cast(i->d_ttd - now), DNSRecordContent::NumberToType(i->d_type).c_str(), i->d_tag, i->d_protobufMessage ? i->d_protobufMessage->length() : 0); + fprintf(fp.get(), "%s %" PRId64 " %s ; tag %d\n", i->d_name.toString().c_str(), static_cast(i->d_ttd - now), DNSRecordContent::NumberToType(i->d_type).c_str(), i->d_tag); } catch(...) { fprintf(fp.get(), "; error printing '%s'\n", i->d_name.empty() ? "EMPTY" : i->d_name.toString().c_str()); diff --git a/pdns/recpacketcache.hh b/pdns/recpacketcache.hh index 7faf793fbe..972e136c0a 100644 --- a/pdns/recpacketcache.hh +++ b/pdns/recpacketcache.hh @@ -51,13 +51,20 @@ using namespace ::boost::multi_index; class RecursorPacketCache: public PacketCache { public: + struct PBData { + std::string d_message; + std::string d_response; + bool d_tagged; + }; + typedef boost::optional OptPBData; + RecursorPacketCache(); bool getResponsePacket(unsigned int tag, const std::string& queryPacket, time_t now, std::string* responsePacket, uint32_t* age, uint32_t* qhash); bool getResponsePacket(unsigned int tag, const std::string& queryPacket, const DNSName& qname, uint16_t qtype, uint16_t qclass, time_t now, std::string* responsePacket, uint32_t* age, uint32_t* qhash); - bool getResponsePacket(unsigned int tag, const std::string& queryPacket, const DNSName& qname, uint16_t qtype, uint16_t qclass, time_t now, std::string* responsePacket, uint32_t* age, vState* valState, uint32_t* qhash, std::string** protobufMessage); - bool getResponsePacket(unsigned int tag, const std::string& queryPacket, DNSName& qname, uint16_t *qtype, uint16_t* qclass, time_t now, std::string* responsePacket, uint32_t* age, vState* valState, uint32_t* qhash, std::string** protobufMessage); + bool getResponsePacket(unsigned int tag, const std::string& queryPacket, const DNSName& qname, uint16_t qtype, uint16_t qclass, time_t now, std::string* responsePacket, uint32_t* age, vState* valState, uint32_t* qhash, OptPBData* pbdata); + bool getResponsePacket(unsigned int tag, const std::string& queryPacket, DNSName& qname, uint16_t *qtype, uint16_t* qclass, time_t now, std::string* responsePacket, uint32_t* age, vState* valState, uint32_t* qhash, OptPBData* pbdata); - void insertResponsePacket(unsigned int tag, uint32_t qhash, std::string&& query, const DNSName& qname, uint16_t qtype, uint16_t qclass, std::string&& responsePacket, time_t now, uint32_t ttl, const vState& valState, pdns::ProtoZero::Message* protobufMessage = nullptr, std::string::size_type pbUnmutablePart = 0); + void insertResponsePacket(unsigned int tag, uint32_t qhash, std::string&& query, const DNSName& qname, uint16_t qtype, uint16_t qclass, std::string&& responsePacket, time_t now, uint32_t ttl, const vState& valState, const OptPBData& pbdata); void doPruneTo(size_t maxSize=250000); uint64_t doDump(int fd); int doWipePacketCache(const DNSName& name, uint16_t qtype=0xffff, bool subtree=false); @@ -80,7 +87,7 @@ private: mutable std::string d_packet; // "I know what I am doing" mutable std::string d_query; #ifdef HAVE_PROTOBUF - mutable boost::optional d_protobufMessage; + mutable OptPBData d_pbdata; #endif mutable time_t d_ttd; mutable time_t d_creation; // so we can 'age' our packets @@ -110,7 +117,7 @@ private: packetCache_t d_packetCache; static bool qrMatch(const packetCache_t::index::type::iterator& iter, const std::string& queryPacket, const DNSName& qname, uint16_t qtype, uint16_t qclass); - bool checkResponseMatches(std::pair::type::iterator, packetCache_t::index::type::iterator> range, const std::string& queryPacket, const DNSName& qname, uint16_t qtype, uint16_t qclass, time_t now, std::string* responsePacket, uint32_t* age, vState* valState, std::string** protobufMessage); + bool checkResponseMatches(std::pair::type::iterator, packetCache_t::index::type::iterator> range, const std::string& queryPacket, const DNSName& qname, uint16_t qtype, uint16_t qclass, time_t now, std::string* responsePacket, uint32_t* age, vState* valState, OptPBData* pbdata); public: void preRemoval(const Entry& entry) diff --git a/pdns/test-recpacketcache_cc.cc b/pdns/test-recpacketcache_cc.cc index 8a4f309a2b..fce6fcc823 100644 --- a/pdns/test-recpacketcache_cc.cc +++ b/pdns/test-recpacketcache_cc.cc @@ -45,16 +45,16 @@ BOOST_AUTO_TEST_CASE(test_recPacketCacheSimple) { pw.commit(); string rpacket((const char*)&packet[0], packet.size()); - rpc.insertResponsePacket(tag, qhash, string(qpacket), qname, QType::A, QClass::IN, string(rpacket), time(0), ttd, vState::Indeterminate, nullptr); + rpc.insertResponsePacket(tag, qhash, string(qpacket), qname, QType::A, QClass::IN, string(rpacket), time(0), ttd, vState::Indeterminate, boost::none); BOOST_CHECK_EQUAL(rpc.size(), 1U); rpc.doPruneTo(0); BOOST_CHECK_EQUAL(rpc.size(), 0U); - rpc.insertResponsePacket(tag, qhash, string(qpacket), qname, QType::A, QClass::IN, string(rpacket), time(0), ttd, vState::Indeterminate, nullptr); + rpc.insertResponsePacket(tag, qhash, string(qpacket), qname, QType::A, QClass::IN, string(rpacket), time(0), ttd, vState::Indeterminate, boost::none); BOOST_CHECK_EQUAL(rpc.size(), 1U); rpc.doWipePacketCache(qname); BOOST_CHECK_EQUAL(rpc.size(), 0U); - rpc.insertResponsePacket(tag, qhash, string(qpacket), qname, QType::A, QClass::IN, string(rpacket), time(0), ttd, vState::Indeterminate, nullptr); + rpc.insertResponsePacket(tag, qhash, string(qpacket), qname, QType::A, QClass::IN, string(rpacket), time(0), ttd, vState::Indeterminate, boost::none); BOOST_CHECK_EQUAL(rpc.size(), 1U); uint32_t qhash2 = 0; bool found = rpc.getResponsePacket(tag, qpacket, time(nullptr), &fpacket, &age, &qhash2); @@ -140,11 +140,11 @@ BOOST_AUTO_TEST_CASE(test_recPacketCache_Tags) { BOOST_CHECK(r1packet != r2packet); /* inserting a response for tag1 */ - rpc.insertResponsePacket(tag1, qhash, string(qpacket), qname, QType::A, QClass::IN, string(r1packet), time(0), ttd, vState::Indeterminate, nullptr); + rpc.insertResponsePacket(tag1, qhash, string(qpacket), qname, QType::A, QClass::IN, string(r1packet), time(0), ttd, vState::Indeterminate, boost::none); BOOST_CHECK_EQUAL(rpc.size(), 1U); /* inserting a different response for tag2, should not override the first one */ - rpc.insertResponsePacket(tag2, qhash, string(qpacket), qname, QType::A, QClass::IN, string(r2packet), time(0), ttd, vState::Indeterminate, nullptr); + rpc.insertResponsePacket(tag2, qhash, string(qpacket), qname, QType::A, QClass::IN, string(r2packet), time(0), ttd, vState::Indeterminate, boost::none); BOOST_CHECK_EQUAL(rpc.size(), 2U); /* remove all responses from the cache */ @@ -152,10 +152,10 @@ BOOST_AUTO_TEST_CASE(test_recPacketCache_Tags) { BOOST_CHECK_EQUAL(rpc.size(), 0U); /* reinsert both */ - rpc.insertResponsePacket(tag1, qhash, string(qpacket), qname, QType::A, QClass::IN, string(r1packet), time(0), ttd, vState::Indeterminate, nullptr); + rpc.insertResponsePacket(tag1, qhash, string(qpacket), qname, QType::A, QClass::IN, string(r1packet), time(0), ttd, vState::Indeterminate, boost::none); BOOST_CHECK_EQUAL(rpc.size(), 1U); - rpc.insertResponsePacket(tag2, qhash, string(qpacket), qname, QType::A, QClass::IN, string(r2packet), time(0), ttd, vState::Indeterminate, nullptr); + rpc.insertResponsePacket(tag2, qhash, string(qpacket), qname, QType::A, QClass::IN, string(r2packet), time(0), ttd, vState::Indeterminate, boost::none); BOOST_CHECK_EQUAL(rpc.size(), 2U); /* remove the responses by qname, should remove both */ @@ -163,7 +163,7 @@ BOOST_AUTO_TEST_CASE(test_recPacketCache_Tags) { BOOST_CHECK_EQUAL(rpc.size(), 0U); /* insert the response for tag1 */ - rpc.insertResponsePacket(tag1, qhash, string(qpacket), qname, QType::A, QClass::IN, string(r1packet), time(0), ttd, vState::Indeterminate, nullptr); + rpc.insertResponsePacket(tag1, qhash, string(qpacket), qname, QType::A, QClass::IN, string(r1packet), time(0), ttd, vState::Indeterminate, boost::none); BOOST_CHECK_EQUAL(rpc.size(), 1U); /* we can retrieve it */ @@ -182,7 +182,7 @@ BOOST_AUTO_TEST_CASE(test_recPacketCache_Tags) { BOOST_CHECK_EQUAL(temphash, qhash); /* adding a response for the second tag */ - rpc.insertResponsePacket(tag2, qhash, string(qpacket), qname, QType::A, QClass::IN, string(r2packet), time(0), ttd, vState::Indeterminate, nullptr); + rpc.insertResponsePacket(tag2, qhash, string(qpacket), qname, QType::A, QClass::IN, string(r2packet), time(0), ttd, vState::Indeterminate, boost::none); BOOST_CHECK_EQUAL(rpc.size(), 2U); /* We still get the correct response for the first tag */ -- 2.47.2