Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make it easier to manipulate messages. #227

Open
partim opened this issue Sep 19, 2023 · 4 comments
Open

Make it easier to manipulate messages. #227

partim opened this issue Sep 19, 2023 · 4 comments
Labels

Comments

@partim
Copy link
Member

partim commented Sep 19, 2023

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
Copy link
Member Author

partim commented Sep 19, 2023

Use Cases

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

  • A stub resolver (or other query-sending client) needs to switch to a different upstream resolver for a query.

    • The query message consists of a header, a single question, and optionally an OPT record. When switching, the message ID in the header needs to change, the UDP payload size in the OPT header may need to change, and certain options in the OPT record may need to be added.
  • A cache wants to store a response received from upstream.

    • The stored message is the same as the received message except that certain options need to be removed from the OPT record and possibly other options added.
  • A cache uses a stored response to create a response from it for a query it received.

    • The outgoing message needs some of the header fields changed (message ID, possibly some flags), it needs to contain either all or a (possibly empty) subset of the records in the three record sections, it needs to construct a new OPT record which may contain certain options from the upstream record.

@partim
Copy link
Member Author

partim commented Sep 19, 2023

Requirements

This comment collects the requirements.

Functional requirements:

  • Selectively change certain field of the message header.
  • Construct each section by including a subset of the existing items and optionally add additional items at any point (or is adding them at the end enough?). The items in the included subset may be non-consecutive in the original section.
  • Separately construct the OPT record similarly by being able to change fields of the OPT header and selectively include some of the original options and add new ones.

Non-functional requirements:

  • No intermediary allocations.

@partim
Copy link
Member Author

partim commented Sep 20, 2023

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
Copy link
Member Author

partim commented Sep 21, 2023

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant