kazu-yamamoto/dns

Handling RData parsing errors

Closed this issue · 2 comments

After months of running daily without problems my scanner threw an exception today due to unexpected malformed data from a remote zone:

ParseError {errorContexts = [], errorMessage = "Failed reading: IPv6 addresses must be 16 bytes long", errorPosition = 1:81 (80)}

This error is from Data.Conduit.Attoparsec. but that library is (correctly) not a documented dependency of Network.DNS and I think that its internal types should not be visible to Network.DNS users. And yet getting garbage in the RData from some remote DNS server is not an entirely unexpected condition. Mostly one sees in Domain fields we don't validate very strictly, so no exceptions are raised, for example, at the moment:

promitterra.nl. IN MX 0 http://fb1.dootall.com.
promitterra.nl. IN MX 10 mr1.dootall.com.
;
spirit-art.nl. IN CNAME http//www.vanhoftenit.nl.

However, sometimes the garbage is more structural, as with unexpected RData lengths for AAAA records.

I see two possible ways to handle this more appropriately than having unexpected exceptions from the conduit parser library. IIn either case catch parser exceptions while parsing RData from packets. Then, either:

  • If it fails to parse, create an RD_PARSERR Int16 ByteString String object which captures the rtype, the raw payload that could not be parsed and the error message from the parser library, or else
  • If it fails to parse return "Left DNS.ParseError" for the whole DNS response

My preference is very much for the first option since one then still gets to see any valid records that are returned allong with the malformed record, and also the maformed payload and its rtype. That said, if it is much simpler to just invalidate the whole reply, given that malformed RData is comparatively rare, I could live with that for now, and the more detailed approach could be taken later...

Thoughts? Comments? Patches?

Example:

aghering.tplinkdns.com. IN AAAA \# 4 5356F1C5

The device returns the RData for its v4 address as the payload for the v6 address.

I would consider this with #103.