diff options
Diffstat (limited to 'apt-pkg')
-rw-r--r-- | apt-pkg/contrib/srvrec.cc | 32 | ||||
-rw-r--r-- | apt-pkg/contrib/srvrec.h | 10 |
2 files changed, 18 insertions, 24 deletions
diff --git a/apt-pkg/contrib/srvrec.cc b/apt-pkg/contrib/srvrec.cc index b4a3d97d2..174668274 100644 --- a/apt-pkg/contrib/srvrec.cc +++ b/apt-pkg/contrib/srvrec.cc @@ -13,7 +13,7 @@ #include <netinet/in.h> #include <arpa/nameser.h> #include <resolv.h> -#include <chrono> +#include <time.h> #include <algorithm> @@ -68,7 +68,6 @@ bool GetSrvRecords(std::string name, std::vector<SrvRec> &Result) unsigned char *pt = answer+sizeof(HEADER)+compressed_name_len+QFIXEDSZ; while ((int)Result.size() < answer_count && pt < answer+answer_len) { - SrvRec rec; u_int16_t type, klass, priority, weight, port, dlen; char buf[MAXDNAME]; @@ -105,11 +104,7 @@ bool GetSrvRecords(std::string name, std::vector<SrvRec> &Result) pt += compressed_name_len; // add it to our class - rec.priority = priority; - rec.weight = weight; - rec.port = port; - rec.target = buf; - Result.push_back(rec); + Result.emplace_back(buf, priority, weight, port); } // implement load balancing as specified in RFC-2782 @@ -173,21 +168,14 @@ SrvRec PopFromSrvRecs(std::vector<SrvRec> &Recs) #endif // shuffle in a very simplistic way for now (equal weights) - std::vector<SrvRec>::iterator I, J; - I = J = Recs.begin(); - for(;I != Recs.end(); ++I) - { - if(I->priority != J->priority) - break; - } - - // FIXME: meeeeh, where to init this properly - unsigned seed = std::chrono::system_clock::now().time_since_epoch().count(); - std::shuffle(J, I, std::default_random_engine(seed)); - - // meh, no pop_front() in std::vector? - SrvRec selected = *Recs.begin(); - Recs.erase(Recs.begin()); + std::vector<SrvRec>::const_iterator I = Recs.begin(); + std::vector<SrvRec>::const_iterator const J = std::find_if(Recs.cbegin(), Recs.cend(), + [&I](SrvRec const &J) { return I->priority != J.priority; }); + + // clock seems random enough. + I += clock() % std::distance(I, J); + SrvRec const selected = std::move(*I); + Recs.erase(I); if (_config->FindB("Debug::Acquire::SrvRecs", false) == true) std::cerr << "PopFromSrvRecs: selecting " << selected.target << std::endl; diff --git a/apt-pkg/contrib/srvrec.h b/apt-pkg/contrib/srvrec.h index e07edc683..2adad03e9 100644 --- a/apt-pkg/contrib/srvrec.h +++ b/apt-pkg/contrib/srvrec.h @@ -26,9 +26,15 @@ class SrvRec int random_number_range_end; int random_number_range_max; - bool operator<(SrvRec const &other) const { - return this->priority < other.priority; + bool operator<(SrvRec const &other) const { + return this->priority < other.priority; } + + SrvRec(std::string const Target, u_int16_t const Priority, + u_int16_t const Weight, u_int16_t const Port) : + target(Target), priority(Priority), weight(Weight), port(Port), + random_number_range_start(0), random_number_range_end(0), + random_number_range_max(0) {} }; /** \brief Get SRV records from host/port (builds the query string internally) |