From d22885557fb0b06036c98a86bed68c1bd93291c5 Mon Sep 17 00:00:00 2001 From: kenshin Date: Fri, 26 Jul 2013 12:06:16 +0800 Subject: [PATCH] read local hosts file --- godns.conf | 5 +++++ handler.go | 8 ++++++-- hosts.go | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++ settings.go | 6 ++++++ 4 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 hosts.go diff --git a/godns.conf b/godns.conf index d6bd407..7a312f3 100644 --- a/godns.conf +++ b/godns.conf @@ -32,3 +32,8 @@ file = "" backend = "memory" expire = 600 # 10 minutes maxcount = 100000 + +[hosts] +host-file = "/etc/hosts" +redis-key = "godns:hosts" + diff --git a/handler.go b/handler.go index 53a70d2..0a21e68 100644 --- a/handler.go +++ b/handler.go @@ -71,7 +71,7 @@ func (h *GODNSHandler) do(net string, w dns.ResponseWriter, req *dns.Msg) { key := KeyGen(Q) // Only query cache when qtype == 'A' , qclass == 'IN' - if q.Qtype == dns.TypeA && q.Qclass == dns.ClassINET { + if h.isIPQuery(q) { mesg, err := h.cache.Get(key) if err != nil { Debug("%s didn't hit cache: %s", Q.String(), err) @@ -94,7 +94,7 @@ func (h *GODNSHandler) do(net string, w dns.ResponseWriter, req *dns.Msg) { w.WriteMsg(mesg) - if q.Qtype == dns.TypeA && q.Qclass == dns.ClassINET { + if h.isIPQuery(q) { err = h.cache.Set(key, mesg) if err != nil { @@ -113,3 +113,7 @@ 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) } + +func (h *GODNSHandler) isIPQuery(q dns.Question) bool { + return q.Qtype == dns.TypeA && q.Qclass == dns.ClassINET +} diff --git a/hosts.go b/hosts.go new file mode 100644 index 0000000..c448765 --- /dev/null +++ b/hosts.go @@ -0,0 +1,59 @@ +package main + +import ( + "github.com/hoisie/redis" + // "github.com/miekg/dns" + "fmt" + "io/ioutil" +) + +type HostsQueryFaild struct { + domain string +} + +func (e HostsQueryFaild) Error() string { + return e.domain + " hosts match failed" +} + +func readLocalHostsFile(file string) map[string]string { + var hosts = make(map[string]string) + f, _ := os.Open(file) + scanner := bufio.NewScanner(f) + for scanner.Scan() { + + line := scanner.Text() + line = strings.TrimSpace(line) + + if strings.HasPrefix(line, "#") || line == "" { + continue + } + + sli := strings.Split(line, " ") + if len(sli) == 1 { + sli = strings.Split(line, "\t") + } + + if len(sli) < 2 { + continue + } + + domain := sli[len(sli)-1] + ip := sli[0] + if !isDomain(domain) || !isIP(ip) { + continue + } + + hosts[domain] = ip + } + return hosts +} + +func isDomain(domain string) bool { + match, _ := regexp.MatchString("^[a-z]", domain) + return match +} + +func isIP(ip string) bool { + match, _ := regexp.MatchString("^[1-9]", ip) + return match +} diff --git a/settings.go b/settings.go index d3ff306..30a89f9 100644 --- a/settings.go +++ b/settings.go @@ -19,6 +19,7 @@ type Settings struct { Redis RedisSettings `toml:"redis"` Log LogSettings `toml:"log"` Cache CacheSettings `toml:"cache"` + Hosts HostsSettings `toml:"hosts"` } type ResolvSettings struct { @@ -48,6 +49,11 @@ type CacheSettings struct { Maxcount int } +type HostsSettings struct { + HostsFile string `toml:"host-file"` + RedisKey string `toml:"redis-key"` +} + func init() { var configFile string