Merge branch 'pr394': Add localDomain option to weavedns
Improve the DNS server configuration mechanism. The new configuration system includes the ability to specify a different domain name other than ".weave.local".
This commit is contained in:
commit
48ef098518
6 files changed
+132
-61
No files matched your search
@@ -35,7 +35,7 @@ func (s *MDNSServer) addrIsLocal(testaddr net.Addr) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (s *MDNSServer) Start(ifi *net.Interface) error {
|
||||
func (s *MDNSServer) Start(ifi *net.Interface, localDomain string) error {
|
||||
conn, err := LinkLocalMulticastListener(ifi)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -69,7 +69,7 @@ func (s *MDNSServer) Start(ifi *net.Interface) error {
|
||||
})
|
||||
|
||||
mux := dns.NewServeMux()
|
||||
mux.HandleFunc(LOCAL_DOMAIN, handleLocal)
|
||||
mux.HandleFunc(localDomain, handleLocal)
|
||||
mux.HandleFunc(RDNS_DOMAIN, handleReverse)
|
||||
|
||||
go dns.ActivateAndServe(nil, conn, mux)
|
||||
|
||||
@@ -44,7 +44,7 @@ func TestServerSimpleQuery(t *testing.T) {
|
||||
|
||||
mdnsServer, err := NewMDNSServer(zone)
|
||||
wt.AssertNoErr(t, err)
|
||||
err = mdnsServer.Start(nil)
|
||||
err = mdnsServer.Start(nil, DEFAULT_LOCAL_DOMAIN)
|
||||
wt.AssertNoErr(t, err)
|
||||
|
||||
var receivedAddr net.IP
|
||||
|
||||
+81
-41
@@ -9,8 +9,11 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
LOCAL_DOMAIN = "weave.local."
|
||||
UDPBufSize = 4096 // bigger than the default 512
|
||||
DEFAULT_LOCAL_DOMAIN = "weave.local." // The default name used for the local domain
|
||||
DEFAULT_SERVER_PORT = 53 // The default server port
|
||||
DEFAULT_CLI_CFG_FILE = "/etc/resolv.conf" // default "resolv.conf" file to try to load
|
||||
DEFAULT_UDP_BUFLEN = 4096 // bigger than the default 512
|
||||
DEFAULT_IFACE_NAME = "default interface"
|
||||
)
|
||||
|
||||
func makeDNSFailResponse(r *dns.Msg) *dns.Msg {
|
||||
@@ -21,59 +24,95 @@ func makeDNSFailResponse(r *dns.Msg) *dns.Msg {
|
||||
return m
|
||||
}
|
||||
|
||||
type DNSServer struct {
|
||||
config *dns.ClientConfig
|
||||
zone Zone
|
||||
iface *net.Interface
|
||||
port int
|
||||
udpSrv *dns.Server
|
||||
tcpSrv *dns.Server
|
||||
type DNSServerConfig struct {
|
||||
// (Optional) client config file for resolving upstream servers
|
||||
UpstreamCfgFile string
|
||||
// (Optional) DNS client config for the fallback server(s)
|
||||
UpstreamCfg *dns.ClientConfig
|
||||
// (Optional) port number (for TCP and UDP)
|
||||
Port int
|
||||
// (Optional) local domain (ie, "weave.local.")
|
||||
LocalDomain string
|
||||
}
|
||||
|
||||
// Creates a new DNS server with a given config
|
||||
func NewDNSServer(config *dns.ClientConfig, zone Zone, iface *net.Interface, port int) *DNSServer {
|
||||
return &DNSServer{
|
||||
config: config,
|
||||
type DNSServer struct {
|
||||
udpSrv *dns.Server
|
||||
tcpSrv *dns.Server
|
||||
mdnsCli *MDNSClient
|
||||
mdnsSrv *MDNSServer
|
||||
zone Zone
|
||||
iface *net.Interface
|
||||
upstream *dns.ClientConfig
|
||||
|
||||
Domain string // the local domain
|
||||
IfaceName string // the interface where mDNS is working on
|
||||
ListenAddr string // the address the server is listening at
|
||||
}
|
||||
|
||||
// Creates a new DNS server
|
||||
func NewDNSServer(config DNSServerConfig, zone Zone, iface *net.Interface) (s *DNSServer, err error) {
|
||||
s = &DNSServer{
|
||||
zone: zone,
|
||||
iface: iface,
|
||||
port: port,
|
||||
|
||||
Domain: DEFAULT_LOCAL_DOMAIN,
|
||||
IfaceName: DEFAULT_IFACE_NAME,
|
||||
ListenAddr: fmt.Sprintf(":%d", DEFAULT_SERVER_PORT),
|
||||
}
|
||||
}
|
||||
|
||||
// Start the DNS server
|
||||
func (s *DNSServer) Start() error {
|
||||
Info.Printf("WeaveDNS server starting...")
|
||||
|
||||
mdnsClient, err := NewMDNSClient()
|
||||
CheckFatal(err)
|
||||
|
||||
ifaceName := "default interface"
|
||||
if s.iface != nil {
|
||||
ifaceName = s.iface.Name
|
||||
// fill empty parameters with defaults...
|
||||
if config.Port != 0 {
|
||||
s.ListenAddr = fmt.Sprintf(":%d", config.Port)
|
||||
}
|
||||
if len(config.LocalDomain) > 0 {
|
||||
s.Domain = config.LocalDomain
|
||||
}
|
||||
if config.UpstreamCfg != nil {
|
||||
s.upstream = config.UpstreamCfg
|
||||
} else {
|
||||
cfgFile := DEFAULT_CLI_CFG_FILE
|
||||
if len(config.UpstreamCfgFile) > 0 {
|
||||
cfgFile = config.UpstreamCfgFile
|
||||
}
|
||||
if s.upstream, err = dns.ClientConfigFromFile(cfgFile); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
s.mdnsCli, err = NewMDNSClient()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
s.mdnsSrv, err = NewMDNSServer(s.zone)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if iface != nil {
|
||||
s.IfaceName = iface.Name
|
||||
}
|
||||
Info.Printf("Using mDNS on %s", ifaceName)
|
||||
err = mdnsClient.Start(s.iface)
|
||||
CheckFatal(err)
|
||||
|
||||
// create two DNS request multiplexerers, depending on the protocol used by clients
|
||||
// (we use the same protocol for asking upstream servers)
|
||||
mux := func(client *dns.Client) *dns.ServeMux {
|
||||
m := dns.NewServeMux()
|
||||
m.HandleFunc(LOCAL_DOMAIN, s.queryHandler([]Lookup{s.zone, mdnsClient}))
|
||||
m.HandleFunc(RDNS_DOMAIN, s.rdnsHandler([]Lookup{s.zone, mdnsClient}, client))
|
||||
m.HandleFunc(s.Domain, s.queryHandler([]Lookup{s.zone, s.mdnsCli}))
|
||||
m.HandleFunc(RDNS_DOMAIN, s.rdnsHandler([]Lookup{s.zone, s.mdnsCli}, client))
|
||||
m.HandleFunc(".", s.notUsHandler(client))
|
||||
return m
|
||||
}
|
||||
|
||||
mdnsServer, err := NewMDNSServer(s.zone)
|
||||
CheckFatal(err)
|
||||
s.udpSrv = &dns.Server{Addr: s.ListenAddr, Net: "udp", Handler: mux(&dns.Client{Net: "udp", UDPSize: DEFAULT_UDP_BUFLEN})}
|
||||
s.tcpSrv = &dns.Server{Addr: s.ListenAddr, Net: "tcp", Handler: mux(&dns.Client{Net: "tcp"})}
|
||||
|
||||
err = mdnsServer.Start(s.iface)
|
||||
CheckFatal(err)
|
||||
return
|
||||
}
|
||||
|
||||
address := fmt.Sprintf(":%d", s.port)
|
||||
s.udpSrv = &dns.Server{Addr: address, Net: "udp", Handler: mux(&dns.Client{Net: "udp", UDPSize: UDPBufSize})}
|
||||
s.tcpSrv = &dns.Server{Addr: address, Net: "tcp", Handler: mux(&dns.Client{Net: "tcp"})}
|
||||
// Start the DNS server
|
||||
func (s *DNSServer) Start() error {
|
||||
Info.Printf("Using mDNS on %s", s.IfaceName)
|
||||
err := s.mdnsCli.Start(s.iface)
|
||||
CheckFatal(err)
|
||||
err = s.mdnsSrv.Start(s.iface, s.Domain)
|
||||
CheckFatal(err)
|
||||
|
||||
wg := new(sync.WaitGroup)
|
||||
wg.Add(2)
|
||||
@@ -81,7 +120,7 @@ func (s *DNSServer) Start() error {
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
|
||||
Debug.Printf("Listening for DNS on %s (UDP)", address)
|
||||
Debug.Printf("Listening for DNS on %s (UDP)", s.ListenAddr)
|
||||
err = s.udpSrv.ListenAndServe()
|
||||
CheckFatal(err)
|
||||
Debug.Printf("DNS UDP server exiting...")
|
||||
@@ -90,7 +129,7 @@ func (s *DNSServer) Start() error {
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
|
||||
Debug.Printf("Listening for DNS on %s (TCP)", address)
|
||||
Debug.Printf("Listening for DNS on %s (TCP)", s.ListenAddr)
|
||||
err = s.tcpSrv.ListenAndServe()
|
||||
CheckFatal(err)
|
||||
Debug.Printf("DNS TCP server exiting...")
|
||||
@@ -111,6 +150,7 @@ func (s *DNSServer) Stop() error {
|
||||
if err := s.udpSrv.Shutdown(); err != nil {
|
||||
return err
|
||||
}
|
||||
// TODO: shutdown the mDNS client/server
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -160,8 +200,8 @@ func (s *DNSServer) notUsHandler(dnsClient *dns.Client) dns.HandlerFunc {
|
||||
return func(w dns.ResponseWriter, r *dns.Msg) {
|
||||
q := r.Question[0]
|
||||
Debug.Printf("[dns msgid %d] Fallback query: %+v", r.MsgHdr.Id, q)
|
||||
for _, server := range s.config.Servers {
|
||||
reply, _, err := dnsClient.Exchange(r, fmt.Sprintf("%s:%s", server, s.config.Port))
|
||||
for _, server := range s.upstream.Servers {
|
||||
reply, _, err := dnsClient.Exchange(r, fmt.Sprintf("%s:%s", server, s.upstream.Port))
|
||||
if err != nil {
|
||||
Debug.Printf("[dns msgid %d] Network error trying %s (%s)",
|
||||
r.MsgHdr.Id, server, err)
|
||||
|
||||
@@ -25,7 +25,7 @@ func TestUDPDNSServer(t *testing.T) {
|
||||
nonLocalName = "weave.works."
|
||||
testAddr1 = "10.0.2.1"
|
||||
)
|
||||
dnsAddr := fmt.Sprintf("localhost:%d", port)
|
||||
dnsAddr := fmt.Sprintf("127.0.0.1:%d", port)
|
||||
testCIDR1 := testAddr1 + "/24"
|
||||
|
||||
InitDefaultLogging(true)
|
||||
@@ -66,13 +66,14 @@ func TestUDPDNSServer(t *testing.T) {
|
||||
wt.AssertNoErr(t, err)
|
||||
|
||||
config := &dns.ClientConfig{Servers: []string{"127.0.0.1"}, Port: fallbackPort}
|
||||
srv := NewDNSServer(config, zone, nil, port)
|
||||
srv, err := NewDNSServer(DNSServerConfig{UpstreamCfg: config, Port: port}, zone, nil)
|
||||
wt.AssertNoErr(t, err)
|
||||
defer srv.Stop()
|
||||
go srv.Start()
|
||||
time.Sleep(100 * time.Millisecond) // Allow sever goroutine to start
|
||||
|
||||
c := new(dns.Client)
|
||||
c.UDPSize = UDPBufSize
|
||||
c.UDPSize = DEFAULT_UDP_BUFLEN
|
||||
m := new(dns.Msg)
|
||||
m.SetQuestion(successTestName, dns.TypeA)
|
||||
m.RecursionDesired = true
|
||||
@@ -189,14 +190,15 @@ func TestTCPDNSServer(t *testing.T) {
|
||||
|
||||
t.Logf("Creating a WeaveDNS server instance, falling back to 127.0.0.1:%s", fallbackPort)
|
||||
config := &dns.ClientConfig{Servers: []string{"127.0.0.1"}, Port: fallbackPort}
|
||||
srv := NewDNSServer(config, zone, nil, port)
|
||||
srv, err := NewDNSServer(DNSServerConfig{UpstreamCfg: config, Port: port}, zone, nil)
|
||||
wt.AssertNoErr(t, err)
|
||||
defer srv.Stop()
|
||||
go srv.Start()
|
||||
time.Sleep(100 * time.Millisecond) // Allow sever goroutine to start
|
||||
|
||||
t.Logf("Creating a UDP and a TCP client")
|
||||
uc := new(dns.Client)
|
||||
uc.UDPSize = UDPBufSize
|
||||
uc.UDPSize = DEFAULT_UDP_BUFLEN
|
||||
tc := new(dns.Client)
|
||||
tc.Net = "tcp"
|
||||
|
||||
|
||||
Executable
+25
@@ -0,0 +1,25 @@
|
||||
#! /bin/bash
|
||||
|
||||
. ./config.sh
|
||||
|
||||
C1=10.2.56.34
|
||||
C2=10.2.54.91
|
||||
|
||||
start_suite "Resolve names in custom domain"
|
||||
|
||||
run_on $HOST1 sudo $WEAVE stop || true
|
||||
run_on $HOST1 sudo $WEAVE stop-dns || true
|
||||
run_on $HOST1 sudo $WEAVE launch-dns 10.0.0.2/8 --localDomain foo.bar.
|
||||
|
||||
docker_on $HOST1 rm -f c1 c2 || true
|
||||
|
||||
run_on $HOST1 sudo $WEAVE run $C2/24 -t --name=c2 -h seetwo.foo.bar ubuntu
|
||||
run_on $HOST1 sudo $WEAVE run --with-dns $C1/24 -t --name=c1 aanand/docker-dnsutils /bin/sh
|
||||
|
||||
ok=$(docker -H tcp://$HOST1:2375 exec -i c1 sh -c "dig +short seetwo.foo.bar.")
|
||||
assert "echo $ok" "$C2"
|
||||
|
||||
ok=$(docker -H tcp://$HOST1:2375 exec -i c1 sh -c "dig +short -x $C2")
|
||||
assert "echo $ok" "seetwo.foo.bar."
|
||||
|
||||
end_suite
|
||||
+16
-12
@@ -19,6 +19,7 @@ func main() {
|
||||
justVersion bool
|
||||
ifaceName string
|
||||
apiPath string
|
||||
localDomain string
|
||||
fallback string
|
||||
dnsPort int
|
||||
httpPort int
|
||||
@@ -31,10 +32,11 @@ func main() {
|
||||
flag.BoolVar(&justVersion, "version", false, "print version and exit")
|
||||
flag.StringVar(&ifaceName, "iface", "", "name of interface to use for multicast")
|
||||
flag.StringVar(&apiPath, "api", "unix:///var/run/docker.sock", "Path to Docker API socket")
|
||||
flag.StringVar(&localDomain, "localDomain", "", "local domain (ie, 'weave.local.')")
|
||||
flag.IntVar(&wait, "wait", 0, "number of seconds to wait for interface to be created and come up")
|
||||
flag.IntVar(&dnsPort, "dnsport", 53, "port to listen to DNS requests")
|
||||
flag.IntVar(&httpPort, "httpport", 6785, "port to listen to HTTP requests")
|
||||
flag.StringVar(&fallback, "fallback", "", "Fallback server and port (ie, '8.8.8.8:53')")
|
||||
flag.StringVar(&fallback, "fallback", "", "fallback server and port (ie, '8.8.8.8:53')")
|
||||
flag.BoolVar(&watch, "watch", true, "watch the docker socket for container events")
|
||||
flag.BoolVar(&debug, "debug", false, "output debugging info to stderr")
|
||||
flag.Parse()
|
||||
@@ -67,25 +69,27 @@ func main() {
|
||||
}
|
||||
}
|
||||
|
||||
var config *dns.ClientConfig
|
||||
srvConfig := weavedns.DNSServerConfig{
|
||||
Port: dnsPort,
|
||||
LocalDomain: localDomain,
|
||||
}
|
||||
|
||||
if len(fallback) > 0 {
|
||||
fallbackHost, fallbackPort, err := net.SplitHostPort(fallback)
|
||||
if err != nil {
|
||||
Error.Fatal("Fould not parse fallback host and port", err)
|
||||
}
|
||||
config = &dns.ClientConfig{Servers: []string{fallbackHost}, Port: fallbackPort}
|
||||
srvConfig.UpstreamCfg = &dns.ClientConfig{Servers: []string{fallbackHost}, Port: fallbackPort}
|
||||
Debug.Printf("DNS fallback at %s:%s", fallbackHost, fallbackPort)
|
||||
} else {
|
||||
config, err = dns.ClientConfigFromFile("/etc/resolv.conf")
|
||||
if err != nil {
|
||||
Error.Fatal("Failed obtain DNS client configuration", err)
|
||||
}
|
||||
}
|
||||
|
||||
go weavedns.ListenHttp(weavedns.LOCAL_DOMAIN, zone, httpPort)
|
||||
srv := weavedns.NewDNSServer(config, zone, iface, dnsPort)
|
||||
|
||||
go weavedns.ListenHttp(localDomain, zone, httpPort)
|
||||
srv, err := weavedns.NewDNSServer(srvConfig, zone, iface)
|
||||
if err != nil {
|
||||
Error.Fatal("Failed to initialize the WeaveDNS server", err)
|
||||
}
|
||||
err = srv.Start()
|
||||
if err != nil {
|
||||
Error.Fatal("Failed to start server", err)
|
||||
Error.Fatal("Failed to start the WeaveDNS server", err)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user