In order to handle glueless NS referrals, we will have to perform some recursion to resolve them. Since Deadwood uses the select() model, the recursion has to be handled by hand. In addition, since we do multiple in-flight merging, things are a little more complicated.
Here is my current plan:
- We will add three numbers to each outgoing recursive request: recursion_depth (int; can be 16-bit or bigger), parent_id (int 16-bit or bigger), and chain_id (32-bit)
- recursion_depth is how many times we’ve followed a glueless NS record (or incomplete CNAME referral); if this exceeds 32, we stop.
- parent_id is the ID of the request that needs to be solved before we can continue solving this DNS name. For example, if we ask for www.example.com, and the .com DNS servers tell us, without giving us an IP, that the nameservers for example.com are ns1.example.net and (say) ns2.example.net, we hold the current request, and make the parent ID one solving ns1.example.net. Called “parent_id” because multiple recursion attempts might be trying to solve the same name at the same time, but a given recursion attempt only has a single parent_id
- chain_id This is a unique 32-bit number. When we spawn a “parent” request, we first make sure there isn’t a request already in-flight which would cause a loop. This is done because, when spawning a “parent”, the parent has the chain_id as the “child” request; if we find a request already in-flight with the same chain_id, we consider it a loop and give up.