Hacker News new | ask | show | jobs
by tptacek 1604 days ago
This is a surpassingly facile putdown. `miekg/dns` is being used here as a DNS request/response parser library. There's almost nothing interesting about parsing DNS messages. The interesting logic in the DNS is the recursive lookup, which is the part this post captures.

As far as I know (we use the same library for our authority servers) `miekg/dns` doesn't even do recursive lookups.

It's not just that, though. It's also that recursive lookups are the probably the most mystifying aspect of DNS. DNS message parsers are straight-line code; there are lots of them, including in POSIX libc. What you don't have in POSIX libc is a function that does a complete from-the-root recursive lookup for a name; most DNS "client" implementations stop at "send the request to the local recursive cache".

To see that function implemented in such a tiny amount of code is itself super interesting.

Essentially, what you're saying is that the article disappointed you because it purported to be about making pizza, but didn't first specify how to make the oven.

2 comments

I disagree. The entire client connection is being handled by the imported DNS library:

    func dnsQuery(name string, server net.IP) *dns.Msg {
        fmt.Printf("dig -r @%s %s\n", server.String(), name)
        msg := new(dns.Msg)
        msg.SetQuestion(name, dns.TypeA)
        c := new(dns.Client)
        reply, _, _ := c.Exchange(msg, server.String()+":53")
        return reply
    }

    func main() {
        name := os.Args[1]
        if !strings.HasSuffix(name, ".") {
            name = name + "."
        }
        fmt.Println("Result:", resolve(name))
    }
While I agree it's impressively simply laid out and as an exercise good to see people getting hands-on with underpinning protocols (I'm a fan of this), it also does its job as a follow up to her previous blog post on the subject.

People taking umbrage with the title as posted here (and the original site title) are IMO not wrong. The article title has been changed to "A toy DNS resolver" now, so obviously it was contentious enough that she thought to change it.

What do you think an "entire client connection" is? It's a read and a write from a net.Conn. Read client.go's (c *Client) exchange() (the lowercase one). It's 30 lines of code, and that includes stuff like EDNS0, TSIG, and read deadlines that have nothing to do with the functionality the author is demonstrating.

If the author took the time to write a 15 line roundTrip() function that called m.Pack(), udpConn.Write(), udpConn.SetDeadline(1s), and udpConn.Read(), would your argument here evaporate? Then it's not a very good argument, is it?

Opening a connection and performing parsing on record formats is the "heavy lifting" in this example.
Yes, we're clear on where the disagreement is between the two of us.
>Essentially, what you're saying is that the article disappointed you because it purported to be about making pizza, but didn't first specify how to make the oven.

No it's more akin about him saying he made a pizza, but all that was done was import a pizza and then sprinkle some pepperoni on it.

Imagine if I said I made an HTTP server in 6 lines.

    const express = require("express");
    const app = express();
    app.get("/", (req, res) => {
      res.send('Hello World!');
    });
    app.listen(8080);
I think it would be reasonable for people to say that I didn't make a HTTP server in 6 lines.

Just how I used a library to make a HTTP server me and I handled requests/responses, the author of this article used a library to handle DNS requests/responses. The 80 lines figure for making a DNS resolver is misleading when there are 26k lines of Go code (according to cloc) for handling DNS that are just in a library instead of the main file.

You have managed simultaneously to radically underestimate the complexity of Node and Express's HTTP handling, while at the same time radically overestimating the complexity of what miekg/dns is being asked to do here.

The majority of the 20,000 lines of non-test code in miekg/dns are just handlers for record types the author of this article didn't need; much of the rest of it is stuff like zone file parsing and DNSSEC signatures, which again have nothing to do with what the author wrote.

What you conspicuously won't find in miekg/dns: a recursive lookup routine.

>What you conspicuously won't find in miekg/dns: a recursive lookup routine.

Sure, but it implements the building blocks that you need to create one. Those building blocks are going to be where a good chunk of code is going to be. (Yes, there is a lot of code from that library that will be unused)