Peter Stuifzand

Sorting DNS records

I don’t update my DNS records often, but when I do I like these records sorted.

A DNS record consists of the following fields: domain name, type and prio (for some types). I use these fields to determine the order of the records. That is also the order in which these fields should be ordered.

The first insight I had about sorting domains was that the domain names consist of parts separated by a period. The domain names may be strings. But a domain name is actually a reversed array of strings. We map the domain name from “sub.example.com” to [ “com”, “example”, “sub” ]. This puts it in an order that makes lexicographical compare work. To compare domain names is to compare these arrays of parts with a lexicographical compare function.

sub lexicographical_compare(\@\@) {
    my ($a, $b) = @_;
    my $i = 0;
    while ($i < @$a && $i < @$b) {
        my $c = $a->[$i] cmp $b->[$i];
        return $c if $c; # $c != 0;
        $i++;
    }
    return @$a <=> @$b;
}

sub compare_dns_record {
    my ($a, $b) = @_;

    my $c = lexicographical_compare($a->{domain_parts}, $b->{domain_parts});
    return $c if $c;

    $c = $a->{type} cmp $b->{type};
    return $c if $c;

    $c = $a->{prio} <=> $b->{prio};
    return $c;
}

The second insight here is that the record itself can also be compared lexicographically. But this is harder to write in Perl. In Haskell, for example, this is the default for tuples.

© 2023 Peter Stuifzand