Пример #1
0
func TestMXHandle(t *testing.T) {
	msg := &mdns.Msg{}

	zone := &config.Zone{
		MX: `1 test1.mail.server
10 test2.mail.server`,
	}

	question := mdns.Question{
		Name: "test.com",
	}

	mx := &mxHandler{}

	err := mx.Handle(msg, zone, question)
	assert.Nil(t, err)

	expectedMsg := &mdns.Msg{}
	rr, err := mdns.NewRR("test.com. 3600 IN MX 1 test1.mail.server")
	assert.Nil(t, err)
	expectedMsg.Answer = append(expectedMsg.Answer, rr)
	rr, err = mdns.NewRR("test.com. 3600 IN MX 10 test2.mail.server")
	assert.Nil(t, err)
	expectedMsg.Answer = append(expectedMsg.Answer, rr)

	assert.Exactly(t, msg.Answer, expectedMsg.Answer)
}
Пример #2
0
func TestTXTHandle(t *testing.T) {
	msg := &mdns.Msg{}

	zone := &config.Zone{
		TXT: `never gonna
		give you up
`,
	}

	question := mdns.Question{
		Name: "test.com",
	}

	txt := &txtHandler{}

	err := txt.Handle(msg, zone, question)
	assert.Nil(t, err)

	expectedMsg := &mdns.Msg{}
	rr, err := mdns.NewRR("test.com. 3600 IN TXT never gonna")
	assert.Nil(t, err)
	expectedMsg.Answer = append(expectedMsg.Answer, rr)
	rr, err = mdns.NewRR("test.com. 3600 IN TXT give you up")
	assert.Nil(t, err)
	expectedMsg.Answer = append(expectedMsg.Answer, rr)

	assert.Exactly(t, msg.Answer, expectedMsg.Answer)
}
Пример #3
0
// Handle produces reply for NS question
func (n *nsHandler) Handle(msg *mdns.Msg, zone *config.Zone, question mdns.Question) (err error) {
	for _, server := range n.config.DNS.Servers {
		s := strings.Join([]string{
			question.Name,
			"3600",
			"IN",
			"NS",
			server.Name,
		}, " ")

		rr, err := mdns.NewRR(s)
		if err == nil {
			msg.Answer = append(msg.Answer, rr)
		}
	}

	for _, server := range n.config.DNS.Servers {
		s := strings.Join([]string{
			server.Name,
			"3600",
			"IN",
			"A",
			server.IP,
		}, " ")
		rr, err := mdns.NewRR(s)
		if err == nil {
			msg.Extra = append(msg.Extra, rr)
		}
	}
	return
}
Пример #4
0
func localRR(hostname string, services map[string]int) (map[string][]dns.RR, error) {
	rrs := map[string][]dns.RR{}
	addrs, err := net.InterfaceAddrs()
	if err != nil {
		return nil, err
	}
	for _, addr := range addrs {
		var ip net.IP
		switch v := addr.(type) {
		case *net.IPNet:
			ip = v.IP
		case *net.IPAddr:
			ip = v.IP
		}
		if ip.IsLoopback() {
			continue
		}
		if ip = ip.To4(); ip != nil {
			for _, record := range []string{
				fmt.Sprintf("%s.local. 10 IN A %s", hostname, ip.String()),
				fmt.Sprintf("%d.%d.%d.%d.in-addr.arpa. 10 IN PTR %s.local.",
					ip[3], ip[2], ip[1], ip[0], hostname),
			} {
				if rr, err := dns.NewRR(record); err != nil {
					return nil, err
				} else {
					rrs[rr.Header().Name] = append(rrs[rr.Header().Name], rr)
				}
			}

			for s, port := range services {
				for _, record := range []string{
					fmt.Sprintf("%s.local. 60 IN PTR %s.%s.local.", s, hostname, s),
					fmt.Sprintf("%s.%s.local. 60 IN SRV 0 0 %d %s.local.",
						hostname, s, port, hostname),
					fmt.Sprintf("%s.%s.local. 60 IN TXT \"\"", hostname, s),
					fmt.Sprintf("_services._dns-sd._udp.local. 60 IN PTR %s.local.", s),
				} {
					if rr, err := dns.NewRR(record); err != nil {
						return nil, err
					} else {
						rrs[rr.Header().Name] = append(rrs[rr.Header().Name], rr)
					}
				}
			}
		}
	}
	return rrs, nil
}
Пример #5
0
func getRecord(domain string, rtype uint16) (rr dns.RR, err error) {
	if *debug {
		Log.Printf("getRecord: domain: %s, resource type: %d\n", domain, rtype)
	}

	key, _ := getKey(domain, rtype)
	var v []byte

	err = bdb.View(func(tx *bolt.Tx) error {
		b := tx.Bucket([]byte(rrBucket))
		v = b.Get([]byte(key))

		if string(v) == "" {
			e := errors.New("Record not found, key: " + key)
			Log.Println(e.Error())

			return e
		}

		return nil
	})

	if err == nil {
		rr, err = dns.NewRR(string(v))
	}

	return rr, err
}
Пример #6
0
func mustNewRR(tb testing.TB, s string) dns.RR {
	rr, err := dns.NewRR(s)
	if err != nil {
		tb.Fatalf("invalid RR %q: %v", s, err)
	}
	return rr
}
Пример #7
0
func mustParseRR(s string) dns.RR {
	rr, err := dns.NewRR(s)
	if err != nil {
		panic(err)
	}
	return rr
}
Пример #8
0
func TestSOAHandle(t *testing.T) {
	saved := now
	now = func() int64 {
		return 0
	}
	defer func() {
		now = saved
	}()

	msg := &mdns.Msg{}

	question := mdns.Question{
		Name: "test.com",
	}

	soa := NewSOAHandler("kitty")

	err := soa.Handle(msg, nil, question)
	assert.Nil(t, err)

	expectedMsg := &mdns.Msg{}
	rr, err := mdns.NewRR("test.com. 3600 IN SOA kitty admin.test.com 0 10000 2400 604800 3600")
	assert.Nil(t, err)
	expectedMsg.Answer = append(expectedMsg.Answer, rr)

	assert.Exactly(t, msg.Answer, expectedMsg.Answer)
}
func mustRR(s string) miekgdns.RR {
	r, err := miekgdns.NewRR(s)
	if err != nil {
		log.Fatal(err)
	}
	return r
}
Пример #10
0
func putincache(results []*dns.Msg) {
	var newans []dns.RR
	var minttl uint32
	var question dns.Question
	for _, r := range results {
		if iscachable(r) {
			//fmt.Printf("%s\n", r.Answer)
			question = r.Question[0]
			for _, ans := range r.Answer {
				//fmt.Printf("%s\n", ans.Header().Ttl)
				if minttl == 0 || minttl > ans.Header().Ttl {
					minttl = ans.Header().Ttl
				}
				if ans.Header().Rrtype == dns.TypeA {
					line := fmt.Sprintf("%s %d IN A %s", r.Question[0].Name, minttl, ans.(*dns.A).A)
					rr, _ := dns.NewRR(line)
					//fmt.Println(rr)
					newans = append(newans, rr)
				}
			}
			//Cache forever for now.
			//cache[r.Question[0]] = cacheobj{ans: r.Answer, expire: time.Now()}
			//fmt.Printf("Cachable for %d\n", minttl)
		}
	}
	fmt.Printf("Putting %d\n", len(newans))
	if len(newans) > 0 {
		cacheput <- putrequest{question: question, ttl: minttl, result: newans}
	}
}
Пример #11
0
func setupSOA(Zone *Zone) {
	label := Zone.Labels[""]

	primaryNs := "ns"

	if record, ok := label.Records[dns.TypeNS]; ok {
		primaryNs = record[0].RR.(*dns.RR_NS).Ns
	}

	s := Zone.Origin + ". 3600 IN SOA " +
		primaryNs + " support.bitnames.com. " +
		strconv.Itoa(Zone.Options.Serial) +
		" 5400 5400 2419200 " +
		strconv.Itoa(Zone.Options.Ttl)

	log.Println("SOA: ", s)

	rr, err := dns.NewRR(s)

	if err != nil {
		log.Println("SOA Error", err)
		panic("Could not setup SOA")
	}

	record := Record{RR: rr}

	label.Records[dns.TypeSOA] = make([]Record, 1)
	label.Records[dns.TypeSOA][0] = record

}
Пример #12
0
// answerQuestion returns resource record answers for the domain in question
func answerQuestion(name string, qtype uint16) []dns.RR {
	answers := make([]dns.RR, 0)

	// get the resource (check memory, cache, and (todo:) upstream)
	r, err := shaman.GetRecord(name)
	if err != nil {
		config.Log.Trace("Failed to get records for '%s' - %v", name, err)
	}

	// validate the records and append correct type to answers[]
	for _, record := range r.StringSlice() {
		entry, err := dns.NewRR(record)
		if err != nil {
			config.Log.Debug("Failed to create RR from record - %v", err)
			continue
		}
		entry.Header().Name = name
		if entry.Header().Rrtype == qtype || qtype == dns.TypeANY {
			answers = append(answers, entry)
		}
	}

	// todo: should `shaman.GetRecord` be wildcard aware (*.domain.com) or is this ok
	// recursively resolve if no records found
	if len(answers) == 0 {
		name = stripSubdomain(name)
		if len(name) > 0 {
			config.Log.Trace("Checking again with '%v'", name)
			return answerQuestion(name, qtype)
		}
	}

	return answers
}
Пример #13
0
func TestPrivateByteSlice(t *testing.T) {
	dns.PrivateHandle("ISBN", TypeISBN, NewISBN)
	defer dns.PrivateHandleRemove(TypeISBN)

	rr, err := dns.NewRR(testrecord)
	if err != nil {
		t.Fatal(err)
	}

	buf := make([]byte, 100)
	off, err := dns.PackRR(rr, buf, 0, nil, false)
	if err != nil {
		t.Errorf("got error packing ISBN: %v", err)
	}

	custrr := rr.(*dns.PrivateRR)
	if ln := custrr.Data.Len() + len(custrr.Header().Name) + 11; ln != off {
		t.Errorf("offset is not matching to length of Private RR: %d!=%d", off, ln)
	}

	rr1, off1, err := dns.UnpackRR(buf[:off], 0)
	if err != nil {
		t.Errorf("got error unpacking ISBN: %v", err)
	}

	if off1 != off {
		t.Errorf("Offset after unpacking differs: %d != %d", off1, off)
	}

	if rr1.String() != testrecord {
		t.Errorf("Record string representation did not match original %#v != %#v", rr1.String(), testrecord)
	} else {
		t.Log(rr1.String())
	}
}
Пример #14
0
func rootZone(w dns.ResponseWriter, req *dns.Msg) {
	m := new(dns.Msg)
	m.SetReply(req)
	rr, _ := dns.NewRR(". 0 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2016110600 1800 900 604800 86400")
	m.Ns = []dns.RR{rr}
	w.WriteMsg(m)
}
Пример #15
0
// Create DNS packet with the config in line with the meta zone
// paper from Vixie
func metazone(w dns.ResponseWriter, req *dns.Msg, c *Config) {
	logPrintf("metazone command")

	// Only called when the class is CHAOS
	// PTR zone.	-> get a list of zone names

	// Top level zone stuff -- list them
	if strings.ToUpper(req.Question[0].Name) == "ZONE." {
		m := new(dns.Msg)
		m.SetReply(req)
		for _, z := range c.Zones {
			ptr, _ := dns.NewRR("zone. 0 CH PTR " + z.Origin)
			m.Answer = append(m.Answer, ptr)
		}
		w.WriteMsg(m)
		return
	}

	// Top level user stuff -- list them
	if strings.ToUpper(req.Question[0].Name) == "USER." {

	}

	// <zone>.ZONE.

	formerr(w, req)
	return
}
Пример #16
0
func ExamplePrivateHandle() {
	dns.PrivateHandle("APAIR", TypeAPAIR, NewAPAIR)
	defer dns.PrivateHandleRemove(TypeAPAIR)

	rr, err := dns.NewRR("miek.nl. APAIR (1.2.3.4    1.2.3.5)")
	if err != nil {
		log.Fatal("could not parse APAIR record: ", err)
	}
	fmt.Println(rr)
	// Output: miek.nl.	3600	IN	APAIR	1.2.3.4 1.2.3.5

	m := new(dns.Msg)
	m.Id = 12345
	m.SetQuestion("miek.nl.", TypeAPAIR)
	m.Answer = append(m.Answer, rr)

	fmt.Println(m)
	// ;; opcode: QUERY, status: NOERROR, id: 12345
	// ;; flags: rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
	//
	// ;; QUESTION SECTION:
	// ;miek.nl.	IN	 APAIR
	//
	// ;; ANSWER SECTION:
	// miek.nl.	3600	IN	APAIR	1.2.3.4 1.2.3.5
}
Пример #17
0
// Publish adds a record, described in RFC XXX
func Publish(r string) error {
	rr, err := dns.NewRR(r)
	if err != nil {
		return err
	}
	local.add <- &entry{rr}
	return nil
}
Пример #18
0
func cacheservice(req chan cacherequest, putter chan putrequest) {
	cache := make(map[dns.Question]cacheobj)
	for {
		select {
		case request := <-req:
			obj, exists := cache[request.msg.Question[0]]
			if exists {
				var allips []string
				var best string
				for _, a := range obj.ans {
					allips = append(allips, fmt.Sprintf("%s", a.(*dns.A).A))
				}
				//fmt.Printf("%s\n", allips)
				if len(allips) > 0 {
					c := make(chan string, 1)
					getbest <- getbestrequest{candidates: allips, channel: c}
					best = <-c
					fmt.Printf("Best: %s\n", best)
				}
				if best != "" {
					//we actually have a winner
					line := fmt.Sprintf("%s %d IN A %s", request.msg.Question[0].Name, 60, best)
					rr, _ := dns.NewRR(line)
					request.channel <- []dns.RR{rr}
				} else {
					//Somehow we dont have a "best" answer
					request.channel <- obj.ans
				}
				//Check if stale
				if obj.expire.Before(time.Now()) {
					//If a stale object was served, make fresh response.
					fmt.Printf("Stale\n")
					go runquery(request.msg, true)
				}
			} else {
				request.channel <- nil
			}
		case put := <-putter:
			//toinsert := false
			var results []dns.RR
			for _, ans := range put.result {
				if ans.Header().Rrtype == dns.TypeA {
					//fmt.Printf("%s\n", ans.(*dns.A).A)
					//ipchan <- fmt.Sprintf("%s", ans.(*dns.A).A)
					results = append(results, ans)
				}
			}
			if len(results) > 0 {
				//Only save the A records if available
				fmt.Printf("Inserting %s : %d\n", put.question, len(results))
				//fmt.Printf("%v\n", put.result)
				cache[put.question] = cacheobj{ans: results, expire: time.Now().Add(time.Duration(put.ttl) * time.Second)}
			}
		}
	}

}
Пример #19
0
func parseRecordList(args []string, zone *route53.HostedZone) []dns.RR {
	records := []dns.RR{}
	origin := fmt.Sprintf("$ORIGIN %s\n", *zone.Name)
	for _, text := range args {
		record, err := dns.NewRR(origin + text)
		fatalIfErr(err)
		records = append(records, record)
	}
	return records
}
/* Function that creates RR records in array from DB (accessible only from dbRespond function) */
func buildRR(handOver []string) (answerHand []dns.RR) {
	for _, stringAns := range handOver {
		temp, err := dns.NewRR(stringAns)
		if err != nil {
			panic(err.Error())
		}
		answerHand = append(answerHand, temp)
	}
	return
}
Пример #21
0
// Deal with the zone options
func configZONE(w dns.ResponseWriter, req *dns.Msg, t *dns.TXT, c *Config) error {
	sx := strings.Split(t.Txt[0], " ")
	if len(sx) == 0 {
		return nil
	}
	switch strings.ToUpper(sx[0]) {
	case "READ":
		if len(sx) != 3 {
			return nil
		}
		logPrintf("config READ %s %s\n", dns.Fqdn(sx[1]), sx[2])
		if e := c.ReadZoneFile(dns.Fqdn(sx[1]), sx[2]); e != nil {
			logPrintf("failed to read %s: %s\n", sx[2], e.Error())
			return e
		}
		logPrintf("config added: READ %s %s\n", dns.Fqdn(sx[1]), sx[2])
		noerr(w, req)
	case "READXFR":
		if len(sx) != 3 {
			return nil
		}
		logPrintf("config READXFR %s %s\n", dns.Fqdn(sx[1]), sx[2])
		if e := c.ReadZoneXfr(dns.Fqdn(sx[1]), sx[2]); e != nil {
			logPrintf("failed to axfr %s: %s\n", sx[2], e.Error())
			return e
		}
		logPrintf("config added: READXFR %s %s\n", dns.Fqdn(sx[1]), sx[2])
		noerr(w, req)
	case "DROP":
		if len(sx) != 2 {
			return nil
		}
		logPrintf("config DROP %s\n", dns.Fqdn(sx[1]))
		if e := c.DropZone(dns.Fqdn(sx[1])); e != nil {
			logPrintf("Failed to drop %s: %s\n", dns.Fqdn(sx[1]), e.Error())
			return e
		}
		logPrintf("config dropped: DROP %s\n", dns.Fqdn(sx[1]))
		noerr(w, req)
	case "LIST":
		logPrintf("config LIST\n")
		m := new(dns.Msg)
		m.SetReply(req)
		// Add the zones to the additional section
		for zone, _ := range c.Zones {
			a, _ := dns.NewRR("ZONE. TXT \"" + zone + "\"")
			m.Extra = append(m.Extra, a)
		}
		m.SetTsig(userFromTsig(req), dns.HmacMD5, 300, time.Now().Unix())
		w.WriteMsg(m)
	}
	return nil
}
Пример #22
0
func authoritativeDNSHandler(w dns.ResponseWriter, r *dns.Msg) {
	m := new(dns.Msg)
	m.SetReply(r)

	a, err := dns.NewRR("example.com. 3600 IN A 127.0.0.1")
	if err != nil {
		panic(err)
	}
	m.Answer = append(m.Answer, a)

	authority := []string{
		"example.com. 7200 IN NS ns1.isp.net.",
		"example.com. 7200 IN NS ns2.isp.net.",
	}
	for _, rr := range authority {
		a, err := dns.NewRR(rr)
		if err != nil {
			panic(err)
		}
		m.Ns = append(m.Ns, a)
	}

	additional := []string{
		"ns1.isp.net. 7200 IN A 127.0.0.1",
		"ns1.isp.net. 7200 IN AAAA ::1",
		"ns2.isp.net. 7200 IN A 127.0.0.2",
	}
	for _, rr := range additional {
		a, err := dns.NewRR(rr)
		if err != nil {
			panic(err)
		}
		m.Extra = append(m.Extra, a)
	}

	if err := w.WriteMsg(m); err != nil {
		panic(err)
	}
}
Пример #23
0
func TestPrivateText(t *testing.T) {
	dns.PrivateHandle("ISBN", TypeISBN, NewISBN)
	defer dns.PrivateHandleRemove(TypeISBN)

	rr, err := dns.NewRR(testrecord)
	if err != nil {
		t.Fatal(err)
	}
	if rr.String() != testrecord {
		t.Errorf("record string representation did not match original %#v != %#v", rr.String(), testrecord)
	} else {
		t.Log(rr.String())
	}
}
Пример #24
0
// Export the data as dns.RR
func (r *Record) ToDns() (dns.RR, error) {
	rdata, err := r.RdataString()
	if err != nil {
		return nil, err
	}
	rr_string := fmt.Sprintf(
		"%s %d %s %s %s",
		r.DomainName,
		r.Rttl,
		r.Rclass,
		r.Rtype,
		rdata,
	)
	return dns.NewRR(rr_string)
}
Пример #25
0
func TestFit(t *testing.T) {
	m := new(dns.Msg)
	m.SetQuestion("miek.nl", dns.TypeA)

	rr, _ := dns.NewRR("www.miek.nl. IN SRV 10 10 8080 blaat.miek.nl.")
	for i := 0; i < 101; i++ {
		m.Answer = append(m.Answer, rr)
	}
	// Uncompresses length is now 4424. Try trimming this to 1927
	Fit(m, 1927, true)

	if m.Len() > 1927 {
		t.Fatalf("failed to fix message, expected < %d, got %d", 1927, m.Len())
	}
}
Пример #26
0
func TestRFC2136ValidUpdatePacket(t *testing.T) {
	acme.ClearFqdnCache()
	dns.HandleFunc(rfc2136TestZone, serverHandlerPassBackRequest)
	defer dns.HandleRemove(rfc2136TestZone)

	server, addrstr, err := runLocalDNSTestServer("127.0.0.1:0", false)
	if err != nil {
		t.Fatalf("Failed to start test server: %v", err)
	}
	defer server.Shutdown()

	txtRR, _ := dns.NewRR(fmt.Sprintf("%s %d IN TXT %s", rfc2136TestFqdn, rfc2136TestTTL, rfc2136TestValue))
	rrs := []dns.RR{txtRR}
	m := new(dns.Msg)
	m.SetUpdate(rfc2136TestZone)
	m.RemoveRRset(rrs)
	m.Insert(rrs)
	expectstr := m.String()
	expect, err := m.Pack()
	if err != nil {
		t.Fatalf("Error packing expect msg: %v", err)
	}

	provider, err := NewDNSProvider(addrstr, "", "", "")
	if err != nil {
		t.Fatalf("Expected NewDNSProvider() to return no error but the error was -> %v", err)
	}

	if err := provider.Present(rfc2136TestDomain, "", "1234d=="); err != nil {
		t.Errorf("Expected Present() to return no error but the error was -> %v", err)
	}

	rcvMsg := <-reqChan
	rcvMsg.Id = m.Id
	actual, err := rcvMsg.Pack()
	if err != nil {
		t.Fatalf("Error packing actual msg: %v", err)
	}

	if !bytes.Equal(actual, expect) {
		tmp := new(dns.Msg)
		if err := tmp.Unpack(actual); err != nil {
			t.Fatalf("Error unpacking actual msg: %v", err)
		}
		t.Errorf("Expected msg:\n%s", expectstr)
		t.Errorf("Actual msg:\n%v", tmp)
	}
}
Пример #27
0
func (h ErrorHandler) recovery(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) {
	rec := recover()
	if rec == nil {
		return
	}

	state := middleware.State{W: w, Req: r}
	// Obtain source of panic
	// From: https://gist.github.com/swdunlop/9629168
	var name, file string // function name, file name
	var line int
	var pc [16]uintptr
	n := runtime.Callers(3, pc[:])
	for _, pc := range pc[:n] {
		fn := runtime.FuncForPC(pc)
		if fn == nil {
			continue
		}
		file, line = fn.FileLine(pc)
		name = fn.Name()
		if !strings.HasPrefix(name, "runtime.") {
			break
		}
	}

	// Trim file path
	delim := "/coredns/"
	pkgPathPos := strings.Index(file, delim)
	if pkgPathPos > -1 && len(file) > pkgPathPos+len(delim) {
		file = file[pkgPathPos+len(delim):]
	}

	panicMsg := fmt.Sprintf("%s [PANIC %s %s] %s:%d - %v", time.Now().Format(timeFormat), r.Question[0].Name, dns.Type(r.Question[0].Qtype), file, line, rec)
	if h.Debug {
		// Write error and stack trace to the response rather than to a log
		var stackBuf [4096]byte
		stack := stackBuf[:runtime.Stack(stackBuf[:], false)]
		answer := debugMsg(dns.RcodeServerFailure, r)
		// add stack buf in TXT, limited to 255 chars for now.
		txt, _ := dns.NewRR(". IN 0 TXT " + string(stack[:255]))
		answer.Answer = append(answer.Answer, txt)
		state.SizeAndDo(answer)
		w.WriteMsg(answer)
	} else {
		// Currently we don't use the function name, since file:line is more conventional
		h.Log.Printf(panicMsg)
	}
}
Пример #28
0
// update changes the SOA record to have a new serial number to reflect changes to the repository.
func (s *soa) update() {
	s.mux.Lock()
	defer s.mux.Unlock()

	tstamp := uint32(time.Now().Unix())
	refresh := 3600
	retry := refresh
	expire := refresh
	minttl := 100
	soa := fmt.Sprintf("%s 1000 SOA %s %s %d %d %d %d %d", s.zone.dns(), s.self.dns(), s.self.dns(),
		tstamp, refresh, retry, expire, minttl)
	var err error
	if s.soa, err = dns.NewRR(soa); err != nil {
		log.Fatalf("invalid SOA record: %s", err)
	}
}
Пример #29
0
// Handle produces reply for A question
func (a *aHandler) Handle(msg *mdns.Msg, zone *config.Zone, question mdns.Question) (err error) {
	s := strings.Join(
		[]string{
			question.Name,
			"3600",
			"IN",
			"A",
			zone.A,
		}, " ")

	rr, err := mdns.NewRR(s)
	if err == nil {
		msg.Answer = append(msg.Answer, rr)
	}
	return
}
Пример #30
0
func setupSOA(Zone *Zone) {
	label := Zone.Labels[""]

	primaryNs := "ns"

	// log.Println("LABEL", label)

	if label == nil {
		log.Println(Zone.Origin, "doesn't have any 'root' records,",
			"you should probably add some NS records")
		label = Zone.AddLabel("")
	}

	if record, ok := label.Records[dns.TypeNS]; ok {
		primaryNs = record[0].RR.(*dns.NS).Ns
	}

	ttl := Zone.Options.Ttl * 10
	if ttl > 3600 {
		ttl = 3600
	}
	if ttl == 0 {
		ttl = 600
	}

	s := Zone.Origin + ". " + strconv.Itoa(ttl) + " IN SOA " +
		primaryNs + " " + Zone.Options.Contact + " " +
		strconv.Itoa(Zone.Options.Serial) +
		// refresh, retry, expire, minimum are all
		// meaningless with this implementation
		" 5400 5400 1209600 3600"

	// log.Println("SOA: ", s)

	rr, err := dns.NewRR(s)

	if err != nil {
		log.Println("SOA Error", err)
		panic("Could not setup SOA")
	}

	record := Record{RR: rr}

	label.Records[dns.TypeSOA] = make([]Record, 1)
	label.Records[dns.TypeSOA][0] = record

}