Support for NS records
Closed this issue · 12 comments
Support for resolving NS records would be great.
In addition to raw record resolving, how easy would it be to provide a function to find the authoritative name servers for a domain?
(Reason for this request: I'm currently querying TXT records through default_config()
, but that potentially results in caching problems. So I'd like to create a resolver that uses the authoritative nameservers directly.)
Added support for NS records in 52acca7.
In addition to raw record resolving, how easy would it be to provide a function to find the authoritative name servers for a domain?
I'm not sure what you're asking for here. DnsResolver::resolve_record::<Ns>
would give you the list of NS records for a given host.
Wow, you're fast! :) Thanks a lot for your work.
I'm not sure what you're asking for here. DnsResolver::resolve_record:: would give you the list of NS records for a given host.
If I have a subdomain (e.g. sub.example.com) that only has a TXT record associated:
$ dig +short TXT mg.dbrgn.ch
"v=spf1 include:mailgun.org ~all"
If I query this subdomain for NS records, it doesn't have any (but there could be some):
$ dig +short NS mg.dbrgn.ch
$
If I'm not mistaken, the correct thing to do would be to strip the first segment from the domain and try again. Or is that wrong?
Also, when I leave away the "+short" option, then the dig
tool does show an AUTHORITY SECTION
. Is that contained in every response? Or is that cached somehow, or queried each time?
If I'm not mistaken, the correct thing to do would be to strip the first segment from the domain and try again. Or is that wrong?
I don't think there's necessarily a notion of objective "correctness" with respect to this problem, but my DNS knowledge is admittedly limited, so I may be wrong. If you can find a reference for this kind of operation performed by something that's widely found in the wild (e.g. in some popular software), then I'll consider implementing this. Otherwise, I think it would be pretty easy to perform this operation on top of the existing API.
Edit: A reference to an RFC would also suffice, of course.
Hm, it looks like the authoritative nameservers are included in all NS responses, they're just ignored when using dig +short
if they're not set directly on the subdomain.
I got a problem using the NS resolution though. When trying to resolve mg.dbrgn.ch
I get an InvalidName
error. The problem is here:
182 // To prevent an infinite loop, we require the pointer to
183 // point before the start of this name.
184 if offset >= start_pos {
185 return Err(DecodeError::InvalidName);
I inserted some print statements into the code, it ended with the following output:
Len: 192 (11000000)
Offset: 12
Start pos: 176
Len: 5 (101)
Len: 2 (10)
Res: dbrgn.ch.
------
Len: 192 (11000000)
Offset: 101
Start pos: 190
Len: 18 (10010)
Len: 11 (1011)
Len: 192 (11000000)
Offset: 50
Start pos: 190
Len: 3 (11)
Res: v22011081724612999.yourvserver.net.
------
Len: 192 (11000000)
Offset: 101
Start pos: 206
Len: 18 (10010)
Len: 11 (1011)
Len: 192 (11000000)
Offset: 50
Start pos: 206
Len: 3 (11)
Res: v22011081724612999.yourvserver.net.
------
Len: 2 (10)
Len: 8 (1000)
Len: 3 (11)
Res: de.ch-inter.net.
------
Len: 2 (10)
Len: 192 (11000000)
Offset: 41
Start pos: 0
failed to resolve record: error decoding message: invalid name
So for some reason the offset is 41 while the start pos is 0.
In Wireshark it looks like this:
I think the error occured in the "Additional records" section.
I tried to debug some more (I understand now how the references work), but could not find the exact reason why start_pos
is zero...
I think I know what the problem is: The content of a resource record is parsed in isolation, not as part of the whole message. Therefore, if a resource record's data contains a name and that name is expressed using a pointer reference, the parser will get confused by the offset. I'm developing a fix now.
Great, thanks! I already thought it had to do with that.
Only gripe now:
$ cargo run --example lookup_ns dbrgn.ch
Running `target/debug/examples/lookup_ns dbrgn.ch`
NS name=ch.ch-inter.net.
NS name=nl.ch-inter.net.
NS name=v22011081724612999.yourvserver.net.
NS name=de.ch-inter.net.
NS name=nl.ch-inter.net.
NS name=v22011081724612999.yourvserver.net.
NS name=de.ch-inter.net.
NS name=ch.ch-inter.net.
The returned values are a combination of authority records and answer resource records.
I'm not sure whether a regular NS query should return the entries of the authority section at all. Strictly speaking they're not NS records. I could still use them in my case tough.
Do we need separate handing for the two parts?
Yes, this does seem wrong. It's the result of me not having understood DNS very well as I began implementing this. I'm pushing a fix now; resolver requests will check only records in the answer section. If an application wants to look at other sections, it will need to use DnsResolver::send_message
to view the entire message.
Sounds good!
I think we can close this now :)