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:
Roland C. Dowdeswell
2016-03-10 17:06:52 -05:00
committed by Viktor Dukhovni
parent 44a1a2a273
commit eb682c1bf4

View File

@@ -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++;