package main import ( "github.com/miekg/dns" . "launchpad.net/gocheck" "net" "strings" "time" ) const ( PORT = ":8853" ) type ServeSuite struct { } var _ = Suite(&ServeSuite{}) func (s *ServeSuite) SetUpSuite(c *C) { // log.Println("Setting up serve test suite") Zones := make(Zones) setupPgeodnsZone(Zones) zonesReadDir("dns", Zones) go listenAndServe(PORT) time.Sleep(200 * time.Millisecond) } func (s *ServeSuite) TestServing(c *C) { r := exchange(c, "_status.pgeodns.", dns.TypeTXT) txt := r.Answer[0].(*dns.TXT).Txt[0] if !strings.HasPrefix(txt, "{") { c.Log("Unexpected result for _status.pgeodns", txt) c.Fail() } r = exchange(c, "bar.test.example.com.", dns.TypeA) ip := r.Answer[0].(*dns.A).A c.Check(ip.String(), Equals, "192.168.1.2") r = exchange(c, "test.example.com.", dns.TypeSOA) soa := r.Answer[0].(*dns.SOA) serial := soa.Serial c.Check(int(serial), Equals, 3) // no AAAA records for 'bar', so check we get a soa record back r = exchange(c, "test.example.com.", dns.TypeAAAA) soa2 := r.Ns[0].(*dns.SOA) c.Check(soa, DeepEquals, soa2) // CNAMEs r = exchange(c, "www.test.example.com.", dns.TypeA) c.Check(r.Answer[0].(*dns.CNAME).Target, Equals, "geo.bitnames.com.") // MX r = exchange(c, "test.example.com.", dns.TypeMX) c.Check(r.Answer[0].(*dns.MX).Mx, Equals, "mx.example.net.") c.Check(r.Answer[1].(*dns.MX).Mx, Equals, "mx2.example.net.") c.Check(r.Answer[1].(*dns.MX).Preference, Equals, uint16(20)) } func (s *ServeSuite) TestServingAliases(c *C) { // Alias, no geo matches r := exchange(c, "bar-alias.test.example.com.", dns.TypeA) ip := r.Answer[0].(*dns.A).A c.Check(ip.String(), Equals, "192.168.1.2") // Alias to a cname record r = exchange(c, "www-alias.test.example.com.", dns.TypeA) c.Check(r.Answer[0].(*dns.CNAME).Target, Equals, "geo.bitnames.com.") // Alias returning a cname, with geo overrides r = exchangeSubnet(c, "www-alias.test.example.com.", dns.TypeA, "194.239.134.1") c.Check(r.Answer, HasLen, 1) if len(r.Answer) > 0 { c.Check(r.Answer[0].(*dns.CNAME).Target, Equals, "geo-europe.bitnames.com.") } } func (s *ServeSuite) TestServingEDNS(c *C) { // MX test r := exchangeSubnet(c, "test.example.com.", dns.TypeMX, "194.239.134.1") c.Check(r.Answer, HasLen, 1) if len(r.Answer) > 0 { c.Check(r.Answer[0].(*dns.MX).Mx, Equals, "mx-eu.example.net.") } c.Log("Testing www.test.example.com from .dk, should match www.europe (a cname)") r = exchangeSubnet(c, "www.test.example.com.", dns.TypeA, "194.239.134.1") c.Check(r.Answer, HasLen, 1) if len(r.Answer) > 0 { c.Check(r.Answer[0].(*dns.CNAME).Target, Equals, "geo-europe.bitnames.com.") } } func exchangeSubnet(c *C, name string, dnstype uint16, ip string) *dns.Msg { msg := new(dns.Msg) msg.SetQuestion(name, dnstype) o := new(dns.OPT) o.Hdr.Name = "." o.Hdr.Rrtype = dns.TypeOPT e := new(dns.EDNS0_SUBNET) e.Code = dns.EDNS0SUBNET e.SourceScope = 0 e.Address = net.ParseIP(ip) e.Family = 1 // IP4 e.SourceNetmask = net.IPv4len * 8 o.Option = append(o.Option, e) msg.Extra = append(msg.Extra, o) c.Log("msg", msg) return dorequest(c, msg) } func exchange(c *C, name string, dnstype uint16) *dns.Msg { msg := new(dns.Msg) msg.SetQuestion(name, dnstype) return dorequest(c, msg) } func dorequest(c *C, msg *dns.Msg) *dns.Msg { cli := new(dns.Client) r, _, err := cli.Exchange(msg, "127.0.0.1"+PORT) if err != nil { c.Log("err", err) c.Fail() } return r }