From 953a577ba29a553c22a08aefe0e1ecec7a4189d0 Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Thu, 2 Oct 2014 18:06:16 +0100 Subject: [PATCH] Add multicast --- dns/main.go | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/dns/main.go b/dns/main.go index 2de4225b..f9182274 100644 --- a/dns/main.go +++ b/dns/main.go @@ -19,7 +19,26 @@ func makeDNSReply(r *dns.Msg, name string, addr net.IP) *dns.Msg { return m } +var mdnsClient *weavedns.MDNSClient + +func handleMDNS(w dns.ResponseWriter, r *dns.Msg) { + // Here we have to handle both requests incoming, responses to queries + // we sent out, and responses to queries that other nodes sent + // And we also get to see our own queries! + if len(r.Answer) > 0 { + mdnsClient.HandleResponse(r) + } else if len(r.Question) > 0 { + q := r.Question[0] + ip, err := zone.MatchLocal(q.Name) + if err == nil { + m := makeDNSReply(r, q.Name, net.ParseIP(ip)) + mdnsClient.SendResponse(m) + } + } +} + func handleLocal(w dns.ResponseWriter, r *dns.Msg) { + log.Printf("Received message:", r) q := r.Question[0] ip, err := zone.MatchLocal(q.Name) if err == nil { @@ -27,6 +46,17 @@ func handleLocal(w dns.ResponseWriter, r *dns.Msg) { w.WriteMsg(m) } else { log.Printf("Failed lookup for %s", q.Name) + // We don't know the answer; see if someone else does + channel := make(chan *weavedns.ResponseA, 4) + go func() { + 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) + } + // FIXME: need to add a time-out either here or in mdnsClient + }() + mdnsClient.SendQuery(q.Name, dns.TypeA, channel) } return } @@ -35,5 +65,20 @@ func main() { LocalServeMux := dns.NewServeMux() LocalServeMux.HandleFunc("local", handleLocal) go weavedns.ListenHttp(zone) + + MDNSServeMux := dns.NewServeMux() + MDNSServeMux.HandleFunc("local", handleMDNS) + + conn, err := weavedns.LinkLocalMulticastListener() + if err != nil { + log.Fatal(err) + } + mdnsClient, err = weavedns.NewMDNSClient() + if err != nil { + log.Fatal(err) + } + + go dns.ActivateAndServe(nil, conn, MDNSServeMux) + dns.ListenAndServe(":5300", "udp", LocalServeMux) }