diff --git a/README.MD b/README.MD index b32b4d9..72de9a6 100644 --- a/README.MD +++ b/README.MD @@ -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 + +### 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) + + + + + + diff --git a/handler.go b/handler.go index a88ba18..ca132c4 100644 --- a/handler.go +++ b/handler.go @@ -3,6 +3,7 @@ package main import ( "github.com/miekg/dns" // "log" + // "fmt" ) type GODNSHandler struct { @@ -35,13 +36,12 @@ func NewHandler() *GODNSHandler { func (h *GODNSHandler) do(net string, w dns.ResponseWriter, req *dns.Msg) { - qname := req.Question[0].Name - qtype := req.Question[0].Qtype - qclass := req.Question[0].Qclass + q := req.Question[0] + Q := Question{q.Name, dns.TypeToString[q.Qtype], dns.ClassToString[q.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) { 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 +} diff --git a/resolver.go b/resolver.go index 8b3740b..26a24f5 100644 --- a/resolver.go +++ b/resolver.go @@ -3,27 +3,49 @@ package main import ( "fmt" "github.com/miekg/dns" + "strings" "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 { 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{ Net: net, ReadTimeout: r.Timeout(), WriteTimeout: r.Timeout(), } - for _, nameserver := range r.Nameservers() { - r, rtt, _ := c.Exchange(req, nameserver) - fmt.Println(r) - fmt.Println(rtt) + qname := req.Question[0].Name + 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 + } + 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 } - // r,rtt,_:c.Exchange(req, a) + Debug("%s dns query failed", qname) + return nil, ResolvError{qname, r.Nameservers()} }