diff --git a/pdns/dnsrecords.cc b/pdns/dnsrecords.cc index 66e29f1a07e5..a2bf6d8ff02a 100644 --- a/pdns/dnsrecords.cc +++ b/pdns/dnsrecords.cc @@ -341,7 +341,7 @@ boilerplate_conv(SVCB, conv.xfr16BitInt(d_priority); conv.xfrName(d_target, false, true); if (d_priority != 0) { - conv.xfrSvcParamKeyVals(d_params); + conv.xfrSvcParamKeyVals(*d_params.lock()); } ) @@ -349,7 +349,7 @@ boilerplate_conv(HTTPS, conv.xfr16BitInt(d_priority); conv.xfrName(d_target, false, true); if (d_priority != 0) { - conv.xfrSvcParamKeyVals(d_params); + conv.xfrSvcParamKeyVals(*d_params.lock()); } ) @@ -745,58 +745,64 @@ string APLRecordContent::getZoneRepresentation(bool noDot) const { /* APL end */ /* SVCB start */ -bool SVCBBaseRecordContent::autoHint(const SvcParam::SvcParamKey &key) const { - auto p = getParamIt(key); - if (p == d_params.end()) { +bool SVCBBaseRecordContent::autoHint(const SvcParam::SvcParamKey &key) { + auto params = d_params.lock(); + auto p = getParamIt(key, *params); + if (p == params->end()) { return false; } return p->getAutoHint(); } void SVCBBaseRecordContent::setHints(const SvcParam::SvcParamKey &key, const std::vector &addresses) { - auto p = getParamIt(key); - if (p == d_params.end()) { - return; - } std::vector h; h.reserve(h.size() + addresses.size()); h.insert(h.end(), addresses.begin(), addresses.end()); + + auto params = d_params.lock(); + auto p = getParamIt(key, *params); + if (p == params->end()) { + return; + } try { auto newParam = SvcParam(key, std::move(h)); - d_params.erase(p); - d_params.insert(newParam); - } catch(...) { + params->erase(p); + params->insert(newParam); + } catch (...) { // XXX maybe we should SERVFAIL instead? return; } } void SVCBBaseRecordContent::removeParam(const SvcParam::SvcParamKey &key) { - auto p = getParamIt(key); - if (p == d_params.end()) { + auto params = d_params.lock(); + auto p = getParamIt(key, *params); + if (p == params->end()) { return; } - d_params.erase(p); + params->erase(p); } -bool SVCBBaseRecordContent::hasParams() const { - return d_params.size() > 0; +bool SVCBBaseRecordContent::hasParams() { + return !d_params.lock()->empty(); } -bool SVCBBaseRecordContent::hasParam(const SvcParam::SvcParamKey &key) const { - return getParamIt(key) != d_params.end(); +bool SVCBBaseRecordContent::hasParam(const SvcParam::SvcParamKey &key) { + auto params = d_params.lock(); + return getParamIt(key, *params) != params->end(); } -SvcParam SVCBBaseRecordContent::getParam(const SvcParam::SvcParamKey &key) const { - auto p = getParamIt(key); - if (p == d_params.end()) { +SvcParam SVCBBaseRecordContent::getParam(const SvcParam::SvcParamKey &key) { + auto params = d_params.lock(); + auto p = getParamIt(key, *params); + if (p == params->end()) { throw std::out_of_range("No param with key " + SvcParam::keyToString(key)); } return *p; } -set::const_iterator SVCBBaseRecordContent::getParamIt(const SvcParam::SvcParamKey &key) const { - auto p = std::find_if(d_params.begin(), d_params.end(), +set::const_iterator SVCBBaseRecordContent::getParamIt(const SvcParam::SvcParamKey &key, std::set& params) { + auto p = std::find_if(params.begin(), params.end(), [&key](const SvcParam ¶m) { return param.getKey() == key; }); diff --git a/pdns/dnsrecords.hh b/pdns/dnsrecords.hh index 420144875782..39efe3440f5a 100644 --- a/pdns/dnsrecords.hh +++ b/pdns/dnsrecords.hh @@ -26,6 +26,7 @@ #include "dnsparser.hh" #include "dnswriter.hh" +#include "lock.hh" #include "rcpgenerator.hh" #include #include @@ -516,25 +517,25 @@ class SVCBBaseRecordContent : public DNSRecordContent const DNSName& getTarget() const {return d_target;} uint16_t getPriority() const {return d_priority;} // Returns true if a value for |key| was set to 'auto' - bool autoHint(const SvcParam::SvcParamKey &key) const; + bool autoHint(const SvcParam::SvcParamKey &key); // Sets the |addresses| to the existing hints for |key| void setHints(const SvcParam::SvcParamKey &key, const std::vector &addresses); // Removes the parameter for |key| from d_params void removeParam(const SvcParam::SvcParamKey &key); // Whether or not there are any parameter - bool hasParams() const; + bool hasParams(); // Whether or not the param of |key| exists - bool hasParam(const SvcParam::SvcParamKey &key) const; + bool hasParam(const SvcParam::SvcParamKey &key); // Get the parameter with |key|, will throw out_of_range if param isn't there - SvcParam getParam(const SvcParam::SvcParamKey &key) const; + SvcParam getParam(const SvcParam::SvcParamKey &key); protected: - uint16_t d_priority; + LockGuarded> d_params; DNSName d_target; - set d_params; + uint16_t d_priority; // Get the iterator to parameter with |key|, return value can be d_params::end - set::const_iterator getParamIt(const SvcParam::SvcParamKey &key) const; + static set::const_iterator getParamIt(const SvcParam::SvcParamKey &key, set& params); }; class SVCBRecordContent : public SVCBBaseRecordContent