Search code examples
dnsdig

Algorithm for sorting response in a round-robin DNS configuration


I'm trying to implement a sorting algorithm to ensure my DNS library always works with an ordered list of DNS records, even if the response comes from a Round-Robin configuration.

Let's take the following two responses.

First.

$ dig google.com A

; <<>> DiG 9.6.0-APPLE-P2 <<>> google.com A
;; ...

;; ANSWER SECTION:
google.com.  201 IN A 74.125.39.106
google.com.  201 IN A 74.125.39.105
google.com.  201 IN A 74.125.39.147
google.com.  201 IN A 74.125.39.104
google.com.  201 IN A 74.125.39.103
google.com.  201 IN A 74.125.39.99

;; ...

Second.

$ dig google.com A

; <<>> DiG 9.6.0-APPLE-P2 <<>> google.com A
;; ...

;; ANSWER SECTION:
google.com.  119 IN A 74.125.39.147
google.com.  119 IN A 74.125.39.104
google.com.  119 IN A 74.125.39.103
google.com.  119 IN A 74.125.39.99
google.com.  119 IN A 74.125.39.106
google.com.  119 IN A 74.125.39.105

;; ...

They are equal except for the fact the ANSWER section contains the DNS records in different order. I need to apply a sorting algorithm to normalize the answer section.

I already figured out an initial version of the algorithm, but the more I add tests the more I discover uncovered cases. For example, in the following response the order of the first record must be kept unchanged.

$ dig www.google.com A

; <<>> DiG 9.6.0-APPLE-P2 <<>> www.google.com A
;; ...

;; ANSWER SECTION:
www.google.com.  603039 IN CNAME www.l.google.com.
www.l.google.com. 78 IN A 74.125.39.105
www.l.google.com. 78 IN A 74.125.39.104
www.l.google.com. 78 IN A 74.125.39.147
www.l.google.com. 78 IN A 74.125.39.106
www.l.google.com. 78 IN A 74.125.39.99
www.l.google.com. 78 IN A 74.125.39.103

;; ...

Is there any kind of existing implementation/reference I can read in order to extract a suitable algorithm?

UPDATE: Some clarification to my original question. I don't need a library to get DNS records, I've got it. I need to find an efficient algorithm to sort the answer section of a response.

Also, keep in mind the question is not restricted to an A question. The original DNS query might be a NS query, a CNAME query or whatever you want.

I'm using Ruby, but this is not relevant for the question itself.


Solution

  • Depending on the language you're using, putting all the answers in a hash/dictionary with an array for the leafs according to type/address, would probably be simpler.

    I'd recommend tie::sorted::array::lazy if you use perl.