Re: why does resolvd sort nameserver rules

2022-05-11 Thread Theo de Raadt
William Ahern  wrote:

> On Wed, May 11, 2022 at 04:54:02PM +0100, james palmer wrote:
> > i have a local dhcp server running which gives out three nameservers:
> > 
> > - 192.168.0.2 (resolves some local machine names)
> > - 9.9.9.9
> > - 149.112.112.112
> > 
> > on linux, android, and windows the local nameserver takes priority over the 
> > others.
> > on openbsd thanks to the nameservers being sorted by ip address 
> > 149.112.112.112 is chosen first.
> > this causes the local machine names to not resolve.
> > 
> > is there a reason for this behaviour?
> > i would expect the nameservers to be written in the order they are set as 
> > on the dhcp server.
> 
> I have no direct knowledge, but judging from the code in resolvd.c
> handle_route_message and cmp, the sorting is primarily driven by declared
> priority of the source--resolvers associated with a higher priority source
> come first, independent of IP address. However, the relative ordering
> information among a set of proposed resolvers from a particular routing
> message seems to be dropped on the floor, no other information is used to
> sort, and the sort comparator falls back to comparing the address strings
> (using strcmp) to achieve a stable sort.

yes, but you missed a piece: /* Eliminate duplicates */

Duplicates should be eliminated when possible, because libc/asr only
uses the first 5 addresses I think.

Imagine we have a v4 announcement doing 3 addresses, and a v4 "umb"
doing 2 addreses, libc will never get around to using a manual entry at
the end if those dynamic dns servers are in fact not responding.

I was trying to handle that kind of situation heuristically.

Maybe we can avoid the address sort, but still attempt to delete duplicate
addresses, to increasae the odds of reaching a manual entry.

> This could be fixed, assuming the current behavior is broken or undesirable,
> by adding a new member to struct rdns_proposal recording the relative
> ordering of proposals within the incoming routing message (i.e. their index
> in the proposal set), and using that member in the comparator to sort
> addresses of equal priority before resorting to strcmp on the address
> string. This presumes the DHCP advertisement order is preserved in the
> routing message. There other potential nuances, like multiple proposal sets
> (from different routing messages) with the same priority, in which case a
> message counter or other mechanism might also be needed to get a more
> intuitive total ordering.

Naw the qsort() is only sensitive to the address to reduce bigO of the
duplicate elimination.  I think a slightly more clever sort+eliminate chunk
of code would do the job.




Re: why does resolvd sort nameserver rules

2022-05-11 Thread William Ahern
On Wed, May 11, 2022 at 04:54:02PM +0100, james palmer wrote:
> i have a local dhcp server running which gives out three nameservers:
> 
> - 192.168.0.2 (resolves some local machine names)
> - 9.9.9.9
> - 149.112.112.112
> 
> on linux, android, and windows the local nameserver takes priority over the 
> others.
> on openbsd thanks to the nameservers being sorted by ip address 
> 149.112.112.112 is chosen first.
> this causes the local machine names to not resolve.
> 
> is there a reason for this behaviour?
> i would expect the nameservers to be written in the order they are set as on 
> the dhcp server.

I have no direct knowledge, but judging from the code in resolvd.c
handle_route_message and cmp, the sorting is primarily driven by declared
priority of the source--resolvers associated with a higher priority source
come first, independent of IP address. However, the relative ordering
information among a set of proposed resolvers from a particular routing
message seems to be dropped on the floor, no other information is used to
sort, and the sort comparator falls back to comparing the address strings
(using strcmp) to achieve a stable sort.

This could be fixed, assuming the current behavior is broken or undesirable,
by adding a new member to struct rdns_proposal recording the relative
ordering of proposals within the incoming routing message (i.e. their index
in the proposal set), and using that member in the comparator to sort
addresses of equal priority before resorting to strcmp on the address
string. This presumes the DHCP advertisement order is preserved in the
routing message. There other potential nuances, like multiple proposal sets
(from different routing messages) with the same priority, in which case a
message counter or other mechanism might also be needed to get a more
intuitive total ordering.