diff --git a/command/agent/command.go b/command/agent/command.go index f5bdda0121..acfdf16e95 100644 --- a/command/agent/command.go +++ b/command/agent/command.go @@ -17,7 +17,7 @@ import ( // gracefulTimeout controls how long we wait before forcefully terminating var gracefulTimeout = 5 * time.Second -// Command is a Command implementation that runs a Serf agent. +// Command is a Command implementation that runs a Consul agent. // The command will not end unless a shutdown message is sent on the // ShutdownCh. If two messages are sent on the ShutdownCh it will forcibly // exit. @@ -29,6 +29,7 @@ type Command struct { agent *Agent rpcServer *AgentRPC httpServer *HTTPServer + dnsServer *DNSServer } // readConfig is responsible for setup of our configuration using @@ -133,7 +134,7 @@ func (c *Command) setupAgent(config *Config, logOutput io.Writer, logWriter *log } // Start the IPC layer - c.Ui.Output("Starting Serf agent RPC...") + c.Ui.Output("Starting Consul agent RPC...") c.rpcServer = NewAgentRPC(agent, rpcListener, logOutput, logWriter) if config.HTTPAddr != "" { @@ -145,6 +146,17 @@ func (c *Command) setupAgent(config *Config, logOutput io.Writer, logWriter *log } c.httpServer = server } + + if config.DNSAddr != "" { + server, err := NewDNSServer(agent, logOutput, config.DNSAddr) + if err != nil { + agent.Shutdown() + c.Ui.Error(fmt.Sprintf("Error starting dns server: %s", err)) + return err + } + c.dnsServer = server + } + return nil } @@ -188,6 +200,7 @@ func (c *Command) Run(args []string) int { c.Ui.Info(fmt.Sprintf("Advertise addr: '%s'", config.AdvertiseAddr)) c.Ui.Info(fmt.Sprintf(" RPC addr: '%s'", config.RPCAddr)) c.Ui.Info(fmt.Sprintf(" HTTP addr: '%s'", config.HTTPAddr)) + c.Ui.Info(fmt.Sprintf(" DNS addr: '%s'", config.DNSAddr)) c.Ui.Info(fmt.Sprintf(" Encrypted: %#v", config.EncryptKey != "")) c.Ui.Info(fmt.Sprintf(" Server: %v (bootstrap: %v)", config.Server, config.Bootstrap)) diff --git a/command/agent/dns.go b/command/agent/dns.go index 2cef1d8a8e..d55b6aaf7e 100644 --- a/command/agent/dns.go +++ b/command/agent/dns.go @@ -44,7 +44,6 @@ func NewDNSServer(agent *Agent, logOutput io.Writer, bind string) (*DNSServer, e // Async start the DNS Server, handle a potential error errCh := make(chan error, 1) go func() { - srv.logger.Printf("[INFO] dns: starting server at %v", bind) err := server.ListenAndServe() srv.logger.Printf("[ERR] dns: error starting server: %v", err) errCh <- err @@ -67,7 +66,6 @@ func NewDNSServer(agent *Agent, logOutput io.Writer, bind string) (*DNSServer, e return } - srv.logger.Printf("resp %#v", in) if len(in.Answer) == 0 { checkCh <- fmt.Errorf("no response to test message") return @@ -99,8 +97,30 @@ func (d *DNSServer) handleConsul(resp dns.ResponseWriter, req *dns.Msg) { // Always respond with TXT "ok" m := new(dns.Msg) m.SetReply(req) + m.Authoritative = true header := dns.RR_Header{Name: q.Name, Rrtype: dns.TypeTXT, Class: dns.ClassINET, Ttl: 0} txt := &dns.TXT{header, []string{"ok"}} m.Answer = append(m.Answer, txt) + d.addSOA("consul.", m) resp.WriteMsg(m) } + +// addSOA is used to add an SOA record to a message for the given domain +func (d *DNSServer) addSOA(domain string, msg *dns.Msg) { + soa := &dns.SOA{ + Hdr: dns.RR_Header{ + Name: domain, + Rrtype: dns.TypeSOA, + Class: dns.ClassINET, + Ttl: 0, + }, + Ns: "ns." + domain, + Mbox: "postmaster." + domain, + Serial: uint32(time.Now().Unix()), + Refresh: 3600, + Retry: 600, + Expire: 86400, + Minttl: 0, + } + msg.Ns = append(msg.Ns, soa) +}