Moved the server startup code out of main.go
This commit is contained in:
1 parent
d48548b1b7
commit
b1b75c4a8a
2 files changed
+121
-113
No files matched your search
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
Reference in new issue
Block a user