From b1b75c4a8a4d42cc0dadbe4cff00d42af1d7cfa8 Mon Sep 17 00:00:00 2001 From: Michael Bridgen Date: Fri, 10 Oct 2014 11:53:21 +0100 Subject: [PATCH] Moved the server startup code out of main.go --- main.go | 117 ++--------------------------------------------- server/server.go | 117 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 121 insertions(+), 113 deletions(-) create mode 100644 server/server.go diff --git a/main.go b/main.go index c787dc2e..5ebcc087 100644 --- a/main.go +++ b/main.go @@ -2,135 +2,26 @@ package main import ( "flag" - "fmt" - "github.com/miekg/dns" "github.com/zettio/weavedns/server" "log" - "net" - "time" ) -const ( - LOCAL_DOMAIN = "weave" -) - -var zone = new(weavedns.ZoneDb) - -func makeDNSReply(r *dns.Msg, name string, addr net.IP) *dns.Msg { - m := new(dns.Msg) - m.SetReply(r) - hdr := dns.RR_Header{Name: name, Rrtype: dns.TypeA, - Class: dns.ClassINET, Ttl: 3600} - a := &dns.A{hdr, addr} - m.Answer = append(m.Answer, a) - return m -} - -var ( - mdnsClient *weavedns.MDNSClient - mdnsServer *weavedns.MDNSServer -) - -func handleLocal(w dns.ResponseWriter, r *dns.Msg) { - q := r.Question[0] - ip, err := zone.MatchLocal(q.Name) - if err == nil { - m := makeDNSReply(r, q.Name, ip) - w.WriteMsg(m) - } else { - log.Printf("Failed lookup for %s; sending mDNS query", q.Name) - // We don't know the answer; see if someone else does - channel := make(chan *weavedns.ResponseA, 4) - go func() { - // Loop terminates when channel is closed by MDNSClient on timeout - for resp := range channel { - log.Printf("Got address response %s to query %s addr %s", resp.Name, q.Name, resp.Addr) - m := makeDNSReply(r, resp.Name, resp.Addr) - w.WriteMsg(m) - } - }() - mdnsClient.SendQuery(q.Name, dns.TypeA, channel) - } - return -} - -func ensureInterface(ifaceName string, wait int) (iface *net.Interface, err error) { - iface, err = findInterface(ifaceName) - if err == nil || wait == 0 { - return - } - log.Println("Waiting for interface", ifaceName, "to come up") - for ; err != nil && wait > 0; wait -= 1 { - time.Sleep(1 * time.Second) - iface, err = findInterface(ifaceName) - } - if err == nil { - log.Println("Interface", ifaceName, "is up") - } - return -} - -func findInterface(ifaceName string) (iface *net.Interface, err error) { - iface, err = net.InterfaceByName(ifaceName) - if err != nil { - return iface, fmt.Errorf("Unable to find interface %s", ifaceName) - } - if 0 == (net.FlagUp & iface.Flags) { - return iface, fmt.Errorf("Interface %s is not up", ifaceName) - } - return -} - func main() { var ( ifaceName string dnsPort int + httpPort int wait int ) flag.StringVar(&ifaceName, "iface", "", "name of interface to use for multicast") flag.IntVar(&wait, "wait", 0, "number of seconds to wait for interface to be created and come up (defaults to 0)") flag.IntVar(&dnsPort, "dnsport", 53, "port to listen to dns requests (defaults to 53)") + flag.IntVar(&httpPort, "httpport", 6785, "port to listen to HTTP requests (defaults to 6785)") flag.Parse() - var iface *net.Interface = nil - if ifaceName != "" { - var err error - iface, err = ensureInterface(ifaceName, wait) - if err != nil { - log.Fatal(err) - } - } - - LocalServeMux := dns.NewServeMux() - LocalServeMux.HandleFunc(LOCAL_DOMAIN, handleLocal) - go weavedns.ListenHttp(zone) - - var err error - mdnsClient, err = weavedns.NewMDNSClient() + err := weavedns.StartServer(ifaceName, dnsPort, httpPort, wait) if err != nil { - log.Fatal(err) - } else { - log.Printf("Using mDNS on %s", ifaceName) - } - err = mdnsClient.Start(iface) - if err != nil { - log.Fatal(err) - } - mdnsServer, err = weavedns.NewMDNSServer(zone) - if err != nil { - log.Fatal(err) - } - err = mdnsServer.Start(iface) - if err != nil { - log.Fatal(err) - } - - address := fmt.Sprintf(":%d", dnsPort) - err = dns.ListenAndServe(address, "udp", LocalServeMux) - if err != nil { - log.Fatal(err) - } else { - log.Printf("Listening for DNS on %s", address) + log.Fatalf("Failed to start server: %s", err) } } diff --git a/server/server.go b/server/server.go new file mode 100644 index 00000000..3c02e9a8 --- /dev/null +++ b/server/server.go @@ -0,0 +1,117 @@ +package weavedns + +import ( + "fmt" + "github.com/miekg/dns" + "log" + "net" + "time" +) + +const ( + LOCAL_DOMAIN = "weave" +) + +func ensureInterface(ifaceName string, wait int) (iface *net.Interface, err error) { + iface, err = findInterface(ifaceName) + if err == nil || wait == 0 { + return + } + log.Println("Waiting for interface", ifaceName, "to come up") + for ; err != nil && wait > 0; wait -= 1 { + time.Sleep(1 * time.Second) + iface, err = findInterface(ifaceName) + } + if err == nil { + log.Println("Interface", ifaceName, "is up") + } + return +} + +func findInterface(ifaceName string) (iface *net.Interface, err error) { + iface, err = net.InterfaceByName(ifaceName) + if err != nil { + return iface, fmt.Errorf("Unable to find interface %s", ifaceName) + } + if 0 == (net.FlagUp & iface.Flags) { + return iface, fmt.Errorf("Interface %s is not up", ifaceName) + } + return +} + +func queryHandler(zone Zone, mdnsClient *MDNSClient) dns.HandlerFunc { + return func(w dns.ResponseWriter, r *dns.Msg) { + q := r.Question[0] + ip, err := zone.MatchLocal(q.Name) + if err == nil { + m := makeDNSReply(r, q.Name, ip) + w.WriteMsg(m) + } else { + log.Printf("Failed lookup for %s; sending mDNS query", q.Name) + // We don't know the answer; see if someone else does + channel := make(chan *ResponseA, 4) + go func() { + // Loop terminates when channel is closed by MDNSClient on timeout + for resp := range channel { + log.Printf("Got address response %s to query %s addr %s", resp.Name, q.Name, resp.Addr) + m := makeDNSReply(r, resp.Name, resp.Addr) + w.WriteMsg(m) + } + }() + mdnsClient.SendQuery(q.Name, dns.TypeA, channel) + } + return + } +} + +func StartServer(ifaceName string, dnsPort int, httpPort int, wait int) error { + + var zone = new(ZoneDb) + go ListenHttp(zone) + + var ( + mdnsClient *MDNSClient + mdnsServer *MDNSServer + ) + + var iface *net.Interface = nil + if ifaceName != "" { + var err error + iface, err = ensureInterface(ifaceName, wait) + if err != nil { + log.Fatal(err) + } + } + + LocalServeMux := dns.NewServeMux() + LocalServeMux.HandleFunc(LOCAL_DOMAIN, queryHandler(zone, mdnsClient)) + + var err error + mdnsClient, err = NewMDNSClient() + if err != nil { + log.Fatal(err) + } else { + log.Printf("Using mDNS on %s", ifaceName) + } + err = mdnsClient.Start(iface) + if err != nil { + log.Fatal(err) + } + mdnsServer, err = NewMDNSServer(zone) + if err != nil { + log.Fatal(err) + } + err = mdnsServer.Start(iface) + if err != nil { + log.Fatal(err) + } + + address := fmt.Sprintf(":%d", dnsPort) + err = dns.ListenAndServe(address, "udp", LocalServeMux) + if err != nil { + log.Fatal(err) + } else { + log.Printf("Listening for DNS on %s", address) + } + return nil +}