Fix incorrect scaling of weight 0 SRV records
Loosely based on patch by Nico.
This commit is contained in:
@@ -660,10 +660,13 @@ rk_dns_srv_order(struct rk_dns_reply *r)
|
||||
headp = &r->head;
|
||||
|
||||
for (ss = srvs; ss < srvs + num_srv; ) {
|
||||
int sum, zeros, rnd, count;
|
||||
int sum, zeros, rnd, count; /* zeros -> weight scaling */
|
||||
struct rk_resource_record **ee, **tt;
|
||||
/* find the last record with the same priority and count the
|
||||
sum of all weights */
|
||||
|
||||
/*
|
||||
* find the last record with the same priority and count the sum of all
|
||||
* weights
|
||||
*/
|
||||
for (sum = 0, zeros = 0, tt = ss; tt < srvs + num_srv; tt++) {
|
||||
assert(*tt != NULL);
|
||||
if((*tt)->u.srv->priority != (*ss)->u.srv->priority)
|
||||
@@ -672,34 +675,41 @@ rk_dns_srv_order(struct rk_dns_reply *r)
|
||||
if ((*tt)->u.srv->weight == 0)
|
||||
zeros++;
|
||||
}
|
||||
/* With no zeros, add 0 and scale * 1 */
|
||||
sum += zeros ? zeros : zeros++;
|
||||
/* make sure scale (`zeros') is > 0 then scale out */
|
||||
sum += zeros ? 1 : zeros++;
|
||||
sum *= zeros;
|
||||
ee = tt;
|
||||
/* ss is now the first record of this priority and ee is the
|
||||
first of the next */
|
||||
|
||||
/*
|
||||
* ss is now the first record of this priority and ee is the first of
|
||||
* the next or the first past the end of srvs
|
||||
*/
|
||||
while (ss < ee) {
|
||||
rnd = rk_random() % sum + 1;
|
||||
for(count = 0, tt = ss; ; tt++) {
|
||||
for (count = 0, tt = ss; tt < ee; tt++) {
|
||||
if (*tt == NULL)
|
||||
continue;
|
||||
count += (*tt)->u.srv->weight * zeros;
|
||||
continue; /* this one's already been picked */
|
||||
if ((*tt)->u.srv->weight == 0)
|
||||
count++;
|
||||
else
|
||||
count += (*tt)->u.srv->weight * zeros;
|
||||
if (count >= rnd)
|
||||
break;
|
||||
}
|
||||
|
||||
assert(tt < ee);
|
||||
|
||||
/* insert the selected record at the tail (of the head) of
|
||||
the list */
|
||||
/* push the selected record */
|
||||
(*tt)->next = *headp;
|
||||
*headp = *tt;
|
||||
headp = &(*tt)->next;
|
||||
sum -= (*tt)->u.srv->weight * zeros;
|
||||
/*
|
||||
* reduce the sum so the next iteration is sure to reach the random
|
||||
* total after examining all the remaining records.
|
||||
*/
|
||||
if ((*tt)->u.srv->weight == 0)
|
||||
sum--;
|
||||
else
|
||||
sum -= (*tt)->u.srv->weight * zeros;
|
||||
*tt = NULL;
|
||||
while (ss < ee && *ss == NULL)
|
||||
ss++;
|
||||
|
Reference in New Issue
Block a user