diff --git a/dns/main.go b/dns/main.go new file mode 100644 index 00000000..8107bc38 --- /dev/null +++ b/dns/main.go @@ -0,0 +1,34 @@ +package main + +import ( + "github.com/miekg/dns" + "net" + "weavedns" + "log" +) + +var zone = new(weavedns.ZoneDb) + +func handleLocal(w dns.ResponseWriter, r *dns.Msg) { + m := new(dns.Msg) + m.SetReply(r) + q := r.Question[0] + ip, err := zone.MatchLocal(q.Name) + if err == nil { + hdr := dns.RR_Header{Name: q.Name, Rrtype: dns.TypeA, + Class: dns.ClassINET, Ttl: 3600} + a := &dns.A{hdr, net.ParseIP(ip)} + m.Answer = append(m.Answer, a) + } else { + log.Printf("Failed lookup for %s", q.Name) + } + w.WriteMsg(m) + return +} + +func main() { + LocalServeMux := dns.NewServeMux() + LocalServeMux.HandleFunc("local", handleLocal) + go weavedns.ListenHttp(zone) + dns.ListenAndServe(":5300", "udp", LocalServeMux) +} diff --git a/src/weavedns/http.go b/src/weavedns/http.go new file mode 100644 index 00000000..3f598ee3 --- /dev/null +++ b/src/weavedns/http.go @@ -0,0 +1,26 @@ +package weavedns + +import ( + "net/http" + "fmt" + "log" +) + +const ( + UPDATE_PORT = 6785 +) + +func ListenHttp(db Zone) { + http.HandleFunc("/add", func(w http.ResponseWriter, r *http.Request) { + name := r.FormValue("name") + addr := r.FormValue("ip") + weave_ip := r.FormValue("weave_ip") + log.Printf("Adding %s %s %s", name, addr, weave_ip) + db.AddRecord(name, addr, weave_ip) + }) + address := fmt.Sprintf(":%d", UPDATE_PORT) + err := http.ListenAndServe(address, nil) + if err != nil { + log.Fatal("Unable to create http listener: ", err) + } +} diff --git a/src/weavedns/zone.go b/src/weavedns/zone.go new file mode 100644 index 00000000..605f5621 --- /dev/null +++ b/src/weavedns/zone.go @@ -0,0 +1,60 @@ +package weavedns + +import ( + "sync" + "log" + "github.com/miekg/dns" +) + +type Zone interface { + AddRecord(name string, ip string, weave_ip string) error + MatchLocal(name string) (string, error) + MatchGlobal(name string) (string, error) +} + +type Record struct { + Name string + Ip string + WeaveIp string +} + +type ZoneDb struct { + mx sync.RWMutex + recs []Record +} + +type LookupError string + +func (ops LookupError) Error() string { + return string(ops) +} + +// Stop gap. +func (zone ZoneDb) match(name string) (string, error) { + for _, r := range zone.recs { + log.Printf("%s == %s ?", r.Name, name) + if r.Name == name { + return r.WeaveIp, nil + } + } + return "", LookupError(name) +} + +func (zone *ZoneDb) MatchLocal(name string) (string, error) { + zone.mx.Lock() + defer zone.mx.Unlock() + return zone.match(name) +} + +func (zone *ZoneDb) MatchGlobal(name string) (string, error) { + zone.mx.Lock() + defer zone.mx.Unlock() + return zone.match(name) +} + +func (zone *ZoneDb) AddRecord(name string, ip string, weave_ip string) error { + zone.mx.Lock() + defer zone.mx.Unlock() + zone.recs = append(zone.recs, Record{dns.Fqdn(name), ip, weave_ip}) + return nil +}