NLnetLabs / domain

A DNS library for Rust.
https://nlnetlabs.nl/projects/domain/about/
BSD 3-Clause "New" or "Revised" License
349 stars 59 forks source link

Make it easier to manipulate messages. #227

Open partim opened 1 year ago

partim commented 1 year ago

DNS has a lot of components that need to manipulate messages. There are components that store and forward queries such as recursive resolvers or forwarders that receive and cache responses from upstream and need to convert them into the responses sent down. A stub resolver may need to switch from one upstream server to the next and can mostly use the message sent to first one but may need to modify the header or OPT record.

Unfortunately, domain currently has no facilities to do this sort of thing cheaply, i.e., take a message, keep most of it but change certain parts.

This issue aims to collect the requirements and devise a scheme to allow manipulating messages without having to re-build an entire message from scratch.

partim commented 1 year ago

Use Cases

This comment collects the use cases. Feel free to comment below; I’ll then add them here.

partim commented 1 year ago

Requirements

This comment collects the requirements.

Functional requirements:

Non-functional requirements:

partim commented 1 year ago

This is all a bit complicated by name compression. If the goal is only to manipulate the OPT record, then the original compression can be kept. If other records are being added or removed, the message needs to be compressed from scratch.

When reusing compression pointers, they should be checked – they must only point to other regular records, not into the header or the OPT record.

partim commented 1 year ago

Manipulating the OPT record is probably worth having a separate solution for. The input is the non-OPT part of the message and optionally a number of options that the caller wants included. For this three parts result: a new constructed header, the unchanged non-OPT records of the message, and a newly constructed OPT record. If supported, these three parts can then be written using vectored IO.

Since we need this for the client code currently in development, I suggest we start with this now.

The idea would be to create a new message type that is guaranteed to not have an OPT record as input for this process as part of the base module and build the machinery described above as part of the net::client module.