Parsing ip6.arpa DNS PTR replies throws an exception
Platform: GNU/Linux
After constructing a TINS::DNS object with a valid DNS reply packet that contains an ip6.arpa PTR record, DNS::answers() throws a "DNS decompression: pointer loops" exception.
In my testing I used the DNS reply packet created by this dig command:
dig @8.8.8.8 2.2.2.0.4.0.0.0.0.0.0.0.0.0.0.0.5.0.0.0.0.0.0.0.8.0.7.0.1.0.0.2.ip6.arpa ptr
ip6_arpa_dns_reply.pcap.gz
I think the exception gets thrown due to faulty tracking of pointer chains during DNS name decompression. In DNS::compose_name() there is this check
if (pointer_counter++ > 30){
throw dns_decompression_pointer_loops();
}
which throws the exception on my perfectly valid ip6.arpa PTR reply.
~~Instead of counting pointers, I think it could be replaced by tracking the visited offsets for duplicates~~ EDIT: I thought wrong. The pointers cannot be tracked just locally. This is not a working fix.
#include <set>
[ ... ]
std::set<const uint8_t*> visited_ptrs;
[ ... ]
if (!visited_ptrs.insert(ptr).second) {
throw dns_decompression_pointer_loops();
}
[ ... ]
I think the pointer counting and checking should be performed only after following compression pointers instead of for every label, by moving the pointer loop check under the pointer offset check.