From: Charles-Henri Bruyand Date: Fri, 15 Jun 2018 08:52:29 +0000 (+0200) Subject: dnsdist: consistent hash - compute hashes at object initialization X-Git-Tag: dnsdist-1.3.3~148^2~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f2caf6573d34b3a2b0a10642f41f6f1fbdf25706;p=thirdparty%2Fpdns.git dnsdist: consistent hash - compute hashes at object initialization --- diff --git a/pdns/dnsdist-lua.cc b/pdns/dnsdist-lua.cc index 2355d503cc..1b5967f721 100644 --- a/pdns/dnsdist-lua.cc +++ b/pdns/dnsdist-lua.cc @@ -237,7 +237,7 @@ void setupLuaConfig(bool client) return ret; } - ret->weight=weightVal; + ret->setWeight(weightVal); } catch(std::exception& e) { // std::stoi will throw an exception if the string isn't in a value int range @@ -278,7 +278,7 @@ void setupLuaConfig(bool client) } if (vars.count("id")) { - ret->id = boost::lexical_cast(boost::get(vars["id"])); + ret->setId(boost::lexical_cast(boost::get(vars["id"]))); } if(vars.count("checkName")) { diff --git a/pdns/dnsdist.cc b/pdns/dnsdist.cc index d4bffecf98..63789847af 100644 --- a/pdns/dnsdist.cc +++ b/pdns/dnsdist.cc @@ -624,6 +624,29 @@ bool DownstreamState::reconnect() return connected; } +void DownstreamState::hash() +{ + auto w = weight; + hashes.clear(); + while (w > 0) { + std::string uuid = boost::str(boost::format("%s-%d") % id % w); + unsigned int wshash = burtleCI((const unsigned char*)uuid.c_str(), uuid.size(), g_hashperturb); + hashes.insert(wshash); + --w; + } +} + +void DownstreamState::setId(const boost::uuids::uuid& newId) +{ + id = newId; + hash(); +} + +void DownstreamState::setWeight(int newWeight) +{ + weight = newWeight; + hash(); +} DownstreamState::DownstreamState(const ComboAddress& remote_, const ComboAddress& sourceAddr_, unsigned int sourceItf_, size_t numberOfSockets): remote(remote_), sourceAddr(sourceAddr_), sourceItf(sourceItf_) { @@ -636,6 +659,7 @@ DownstreamState::DownstreamState(const ComboAddress& remote_, const ComboAddress for (auto& fd : sockets) { fd = -1; } + hash(); if (!IsAnyAddress(remote)) { reconnect(); @@ -737,17 +761,6 @@ shared_ptr chashed(const NumberedServerVector& servers, const D for (const auto& d: servers) { if (d.second->isUp()) { - if (d.second->hashes.empty()) { - // computes server's points - // @todo check if server's weight can change over time - auto w = d.second->weight; - while (w > 0) { - std::string uuid = boost::str(boost::format("%s-%d") % d.second->id % w); - unsigned int wshash = burtleCI((const unsigned char*)uuid.c_str(), uuid.size(), g_hashperturb); - d.second->hashes.insert(wshash); - --w; - } - } for (const auto& h: d.second->hashes) { // put server's hashes on the circle circle.insert(std::make_pair(h, d.second)); diff --git a/pdns/dnsdist.hh b/pdns/dnsdist.hh index 0a035b6634..0681812df9 100644 --- a/pdns/dnsdist.hh +++ b/pdns/dnsdist.hh @@ -618,6 +618,9 @@ struct DownstreamState return status; } bool reconnect(); + void hash(); + void setId(const boost::uuids::uuid& newId); + void setWeight(int newWeight); }; using servers_t =vector>;