What I learned from making a DNS client in Rust
blog.adamchalmers.com
blog.adamchalmers.com
This is one of the reasons I rather like rust and it's ecosystem: you can delegate "boring" functionality (aka the stuff you need, but aren't interested in writing) to the ecosystem and just focus on the stuff you want to.
Other languages also have a similarly rich ecosystem (python in particular). But compared to python, I find that rust is slightly better; 2 reasons come to mind:
* Docs in rust seem to be slightly better. I think this is partly due to the generally high quality of docs.rs, so crate authors seem to have settled on the idea that some minimal baseline docs are expected.
* Error handling in rust feels better. In the python world, I would see None returned some library functions that didn't really document this possibility, yielding an uncomfortable number of runtime TypeErrors or AttributeErrors due to an unexpected NoneType
What I find annoying about Java is that very major dependencies are either slow-moving, making upgrading to a new Java version quite a challenge, or require constant rewrites with new releases. I've come to expect that upgrading dependencies usually means "the code works except for these methods being a bit different" but in Java libraries the entire API can change on a whim.
The only thing I find "serious" about it is that everyone seems to run ancient versions of Java because their dependencies are impossible to upgrade. It's no wonder that Java 8 seems to be as popular as ever despite the two LTS releases since.
I'm referring to lines 1286-1288 in codec.c, FWIW.
Obviously, you only need to support jumping back per RFC1035 and your code supports both jumping back AND forward, so I'm just telling you this for idle chitchat and so that you know that your code was helpful and I appreciate you putting it out there. Thanks!
Edit: Also, before I forget, this implementation uses recursion even though it's not necessary. https://github.com/google/gopacket/blob/3eaba08943250fd21252...
Between your code, the one linked to above, and djbdns I was totally confused about what the "right" way is. I eventually read RFC1035 and saw that all of your approaches are correct.
Edit 2: Also, DJB has some choice words about the compression scheme. https://github.com/abh/djbdns/blob/0715ca5de14ad5eae2c779c53...
Using recursion didn't even occur to me (and in some places, recursion is verboten, along with memory allocation). As for DJB's comment, while I can agree in general, it seems that the DEFLATE algorithm was documented significantly after DNS (RFC-1950 and RFC-1035).
Indeed. This was the case for my project at work.
With that being said, one can always hand-roll recursion with iteration by pushing the state onto their own local stack. I have done this several times on a 6502.
()a()b(^b)
The pointer goes backwards, but it doesn't go back to the start of a label sequence. So do you track the start of each label? Or just the start of each domain name?Edit: nevermind, I see what you are doing.
It’s a good demonstration of why I like Rust so much. All the pieces were already there, and Rust’s type system ensures that I cannot have any unexpected sources of errors. My error–handling code is honestly pretty crude, but the compiler ensures that I have actually handled them all, and that there can be no surprises. No innocent–looking library functions that – surprise! – can actually throw exceptions.
So after fighting with multithreading in this archane app - I forgot what exactly the problems were - I wrote a very simple resolver that would only be able to handle AAAA lookups. It really is surprisingly simple. I think the more involved part was googling how to retrieve the system's configured DNS servers. ;)
The differences:
I followed this guide rather than the RFCs https://github.com/EmilHernvall/dnsguide/blob/master/chapter...
Mine isn't as polished. The command line parsing and output is more thrown together.
I hardcoded the packet identifier (it's not production code, and I'm only looking up one at a time).
I didn't use any bit manipulation libraries. I can see they would help because DNS packets don't line up their information with the byte boundaries.