The recursion resolve can work

This commit is contained in:
kenshin 2013-07-24 00:37:38 +08:00
parent 5349b53416
commit 22a31dcd98
3 changed files with 54 additions and 11 deletions

View File

@ -14,3 +14,14 @@ Similar as [dnsmasq](http://www.thekelleys.org.uk/dnsmasq/doc.html) ,but support
* Cache records save in memory or redis configurable * Cache records save in memory or redis configurable
### Configuration
All the configuration on godns.conf a TOML formating config file.
More about Toml :[https://github.com/mojombo/toml](https://github.com/mojombo/toml)

View File

@ -3,6 +3,7 @@ package main
import ( import (
"github.com/miekg/dns" "github.com/miekg/dns"
// "log" // "log"
// "fmt"
) )
type GODNSHandler struct { type GODNSHandler struct {
@ -35,13 +36,12 @@ func NewHandler() *GODNSHandler {
func (h *GODNSHandler) do(net string, w dns.ResponseWriter, req *dns.Msg) { func (h *GODNSHandler) do(net string, w dns.ResponseWriter, req *dns.Msg) {
qname := req.Question[0].Name q := req.Question[0]
qtype := req.Question[0].Qtype Q := Question{q.Name, dns.TypeToString[q.Qtype], dns.ClassToString[q.Qclass]}
qclass := req.Question[0].Qclass
Debug("Question: %s %s %s", qname, dns.ClassToString[qclass], dns.TypeToString[qtype]) Debug("Question: %s", Q.String())
h.resolver.Lookup(net, req) mesg, err := h.resolver.Lookup(net, req)
} }
@ -52,3 +52,13 @@ func (h *GODNSHandler) DoTCP(w dns.ResponseWriter, req *dns.Msg) {
func (h *GODNSHandler) DoUDP(w dns.ResponseWriter, req *dns.Msg) { func (h *GODNSHandler) DoUDP(w dns.ResponseWriter, req *dns.Msg) {
h.do("udp", w, req) h.do("udp", w, req)
} }
type Question struct {
qname string
qtype string
qclass string
}
func (q *Question) String() string {
return q.qname + " " + q.qclass + " " + q.qtype
}

View File

@ -3,27 +3,49 @@ package main
import ( import (
"fmt" "fmt"
"github.com/miekg/dns" "github.com/miekg/dns"
"strings"
"time" "time"
) )
type ResolvError struct {
qname string
nameservers []string
}
func (e ResolvError) Error() string {
errmsg := fmt.Sprintf("%s resolv failed on %s", e.qname, strings.Join(e.nameservers, "; "))
return errmsg
}
type Resolver struct { type Resolver struct {
config *dns.ClientConfig config *dns.ClientConfig
} }
func (r *Resolver) Lookup(net string, req *dns.Msg) { func (r *Resolver) Lookup(net string, req *dns.Msg) (message *dns.Msg, err error) {
c := &dns.Client{ c := &dns.Client{
Net: net, Net: net,
ReadTimeout: r.Timeout(), ReadTimeout: r.Timeout(),
WriteTimeout: r.Timeout(), WriteTimeout: r.Timeout(),
} }
for _, nameserver := range r.Nameservers() { qname := req.Question[0].Name
r, rtt, _ := c.Exchange(req, nameserver)
fmt.Println(r)
fmt.Println(rtt)
for _, nameserver := range r.Nameservers() {
r, rtt, err := c.Exchange(req, nameserver)
if err != nil {
Debug("%s socket error on %s", qname, nameserver)
Debug("error:%s", err.Error())
continue
} }
// r,rtt,_:c.Exchange(req, a) if r != nil && r.Rcode != dns.RcodeSuccess {
Debug("%s failed to get an valid answer on %s", qname, nameserver)
continue
}
Debug("%s resolv on %s ttl: %d", qname, nameserver, rtt)
return r, nil
}
Debug("%s dns query failed", qname)
return nil, ResolvError{qname, r.Nameservers()}
} }