Fix weight zero entries when ordering SRV RR results.
In lib/roken/resolve.c, we find rk_dns_srv_order() which re-orders the results of an SRV RR lookup by the algorithm in RFC2782. We note that the algorithm doesn't behave according to the RFC w.r.t. entries of weight zero. We solve this by scaling out the remaining weights by the number of zeros we find at a particular priority level and acting like the zero weights have a weight of one.
This commit is contained in:

committed by
Viktor Dukhovni

parent
44a1a2a273
commit
eb682c1bf4
@@ -660,16 +660,20 @@ rk_dns_srv_order(struct rk_dns_reply *r)
|
|||||||
headp = &r->head;
|
headp = &r->head;
|
||||||
|
|
||||||
for(ss = srvs; ss < srvs + num_srv; ) {
|
for(ss = srvs; ss < srvs + num_srv; ) {
|
||||||
int sum, rnd, count;
|
int sum, zeros, rnd, count;
|
||||||
struct rk_resource_record **ee, **tt;
|
struct rk_resource_record **ee, **tt;
|
||||||
/* find the last record with the same priority and count the
|
/* find the last record with the same priority and count the
|
||||||
sum of all weights */
|
sum of all weights */
|
||||||
for(sum = 0, tt = ss; tt < srvs + num_srv; tt++) {
|
for(sum = 0, zeros = 0, tt = ss; tt < srvs + num_srv; tt++) {
|
||||||
assert(*tt != NULL);
|
assert(*tt != NULL);
|
||||||
if((*tt)->u.srv->priority != (*ss)->u.srv->priority)
|
if((*tt)->u.srv->priority != (*ss)->u.srv->priority)
|
||||||
break;
|
break;
|
||||||
sum += (*tt)->u.srv->weight;
|
sum += (*tt)->u.srv->weight;
|
||||||
|
if ((*tt)->u.srv->weight == 0)
|
||||||
|
zeros++;
|
||||||
}
|
}
|
||||||
|
sum *= zeros;
|
||||||
|
sum += zeros;
|
||||||
ee = tt;
|
ee = tt;
|
||||||
/* ss is now the first record of this priority and ee is the
|
/* ss is now the first record of this priority and ee is the
|
||||||
first of the next */
|
first of the next */
|
||||||
@@ -678,7 +682,9 @@ rk_dns_srv_order(struct rk_dns_reply *r)
|
|||||||
for(count = 0, tt = ss; ; tt++) {
|
for(count = 0, tt = ss; ; tt++) {
|
||||||
if(*tt == NULL)
|
if(*tt == NULL)
|
||||||
continue;
|
continue;
|
||||||
count += (*tt)->u.srv->weight;
|
count += (*tt)->u.srv->weight * zeros;
|
||||||
|
if ((*tt)->u.srv->weight == 0)
|
||||||
|
count++;
|
||||||
if(count >= rnd)
|
if(count >= rnd)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -690,7 +696,9 @@ rk_dns_srv_order(struct rk_dns_reply *r)
|
|||||||
(*tt)->next = *headp;
|
(*tt)->next = *headp;
|
||||||
*headp = *tt;
|
*headp = *tt;
|
||||||
headp = &(*tt)->next;
|
headp = &(*tt)->next;
|
||||||
sum -= (*tt)->u.srv->weight;
|
sum -= (*tt)->u.srv->weight * zeros;
|
||||||
|
if ((*tt)->u.srv->weight == 0)
|
||||||
|
sum--;
|
||||||
*tt = NULL;
|
*tt = NULL;
|
||||||
while(ss < ee && *ss == NULL)
|
while(ss < ee && *ss == NULL)
|
||||||
ss++;
|
ss++;
|
||||||
|
Reference in New Issue
Block a user