summaryrefslogtreecommitdiff
path: root/apt-pkg
diff options
context:
space:
mode:
Diffstat (limited to 'apt-pkg')
-rw-r--r--apt-pkg/contrib/srvrec.cc32
-rw-r--r--apt-pkg/contrib/srvrec.h10
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)