(Re)announcing GoDNS

December 19, 2010


[ post updated to reflect changes in the library ]

This library takes a new, innovative and enterprise ready approach sends and receives queries to and from the DNS.

The library was forked from the official DNS code in Go (in the net package). Since that time Go team has thrown out this code and started to use the system’s C library via a wrapper. I was however struck by the elegance of the code (esp. the pack and unpack functions), so I forked it and added new record types (AAAA, DS, RRSIG, etc.) and turned into a more general DNS API.

The API is slightly different than for instance, Net::DNS or Ldns in that you must create the packet before you hand it over to the resolver:

m := new(dns.Msg)
m.MsgHdr.Recursion_desired = true
m.Question = make([]dns.Question, 1)
m.Question[0] = dns.Question{"miek.nl", dns.TypeSOA, dns.ClassINET}

This is more cumbersome than for instance, this (non-godns) code:

r := new(dns.Resolver)
r.Query("miek.nl", dns.TypeSOA, dns.ClassINET)

But… it does allow for much more flexibility, something that is lacking (IMHO) in todays DNS libraries. Also the resolver object has an optional call-back function that can transform the packet just before it is put on the wire (res.Mangle). Also the resolver runs in a seperate goroutine.

A short program that send, receives and prints out a packet goes something like this:

res := new(dns.Resolver)   // create a new resolver object
res.Servers = []string{""}  // set the nameservers
res.Attempts = 1

m := new(dns.Msg)
m.MsgHdr.Recursion_desired = true    // only set this bit
m.Question = make([]dns.Question, 1) // Alloc space for a question
// set the question
m.Question[0] = dns.Question{"miek.nl", dns.TypeTXT, dns.ClassINET}

in, err := res.Query(m)     // ask the question
fmt.Printf("%v\n", in)      // print the reply message

Code, license and URLs

The code can be found at github. Listed on Go Dashboard under the libs section. The project page on miek.nl is listed here. It is licensed under the same license as the official Go code, because it is forked from that.

There is lots of stuff that still needs implementing, a selection from the current list:

  • EDNS - in a nice and transparent way;
  • DNSSEC validation, DNSSEC types are already there of course;
  • Better error handling;