func (s *Server) Run() { Handler := NewHandler() go Handler.PreparePool() fmt.Println(Handler.resolver.NameserversPool) tcpHandler := dns.NewServeMux() tcpHandler.HandleFunc(".", Handler.DoTCP) udpHandler := dns.NewServeMux() udpHandler.HandleFunc(".", Handler.DoUDP) tcpServer := &dns.Server{Addr: s.Addr(), Net: "tcp", Handler: tcpHandler, ReadTimeout: s.rTimeout, WriteTimeout: s.wTimeout, } udpServer := &dns.Server{Addr: s.Addr(), Net: "udp", Handler: udpHandler, UDPSize: 65535, ReadTimeout: s.rTimeout, WriteTimeout: s.wTimeout, } go s.start(udpServer) go s.start(tcpServer) }
func (s *Server) Run() { Handler := NewHandler() tcpHandler := dns.NewServeMux() tcpHandler.HandleFunc(".", Handler.DoTCP) udpHandler := dns.NewServeMux() udpHandler.HandleFunc(".", Handler.DoUDP) tcpServer := &dns.Server{Addr: s.Addr(), Net: "tcp", Handler: tcpHandler, ReadTimeout: s.rTimeout, WriteTimeout: s.wTimeout} udpServer := &dns.Server{Addr: s.Addr(), Net: "udp", Handler: udpHandler, UDPSize: 65535, ReadTimeout: s.rTimeout, WriteTimeout: s.wTimeout} go s.start(udpServer) go s.start(tcpServer) }
func (s *Server) Run() { tcpResponseTimer := metrics.NewTimer() metrics.Register("request.handler.tcp.response_time", tcpResponseTimer) tcpRequestCounter := metrics.NewCounter() metrics.Register("request.handler.tcp.requests", tcpRequestCounter) tcpAcceptCounter := metrics.NewCounter() metrics.Register("request.handler.tcp.filter_accepts", tcpAcceptCounter) tcpRejectCounter := metrics.NewCounter() metrics.Register("request.handler.tcp.filter_rejects", tcpRejectCounter) udpResponseTimer := metrics.NewTimer() metrics.Register("request.handler.udp.response_time", udpResponseTimer) udpRequestCounter := metrics.NewCounter() metrics.Register("request.handler.udp.requests", udpRequestCounter) udpAcceptCounter := metrics.NewCounter() metrics.Register("request.handler.udp.filter_accepts", udpAcceptCounter) udpRejectCounter := metrics.NewCounter() metrics.Register("request.handler.udp.filter_rejects", udpRejectCounter) resolver := Resolver{etcd: s.etcd, defaultTtl: s.defaultTtl, etcdPrefix: s.prefix} tcpDNShandler := &Handler{ resolver: &resolver, requestCounter: tcpRequestCounter, acceptCounter: tcpAcceptCounter, rejectCounter: tcpRejectCounter, responseTimer: tcpResponseTimer, queryFilterer: s.queryFilterer} udpDNShandler := &Handler{ resolver: &resolver, requestCounter: udpRequestCounter, acceptCounter: udpAcceptCounter, rejectCounter: udpRejectCounter, responseTimer: udpResponseTimer, queryFilterer: s.queryFilterer} udpHandler := dns.NewServeMux() tcpHandler := dns.NewServeMux() tcpHandler.HandleFunc(".", tcpDNShandler.Handle) udpHandler.HandleFunc(".", udpDNShandler.Handle) tcpServer := &dns.Server{Addr: s.Addr(), Net: "tcp", Handler: tcpHandler, ReadTimeout: s.rTimeout, WriteTimeout: s.wTimeout} udpServer := &dns.Server{Addr: s.Addr(), Net: "udp", Handler: udpHandler, UDPSize: 65535, ReadTimeout: s.rTimeout, WriteTimeout: s.wTimeout} go s.start(udpServer) go s.start(tcpServer) }
// Run is a blocking operation that starts the server listening on the DNS ports. func (s *server) Run() error { mux := dns.NewServeMux() mux.Handle(".", s) dnsReadyMsg := func(addr, net string) { if s.config.DNSSEC == "" { log.Printf("skydns: ready for queries on %s for %s://%s [rcache %d]", s.config.Domain, net, addr, s.config.RCache) } else { log.Printf("skydns: ready for queries on %s for %s://%s [rcache %d], signing with %s [scache %d]", s.config.Domain, net, addr, s.config.RCache, s.config.DNSSEC, s.config.SCache) } } s.group.Add(1) go func() { defer s.group.Done() if err := dns.ListenAndServe(s.config.DnsAddr, s.dnsTCPclient.Net, mux); err != nil { log.Fatalf("skydns: %s", err) } }() dnsReadyMsg(s.config.DnsAddr, s.dnsTCPclient.Net) s.group.Add(1) go func() { defer s.group.Done() if err := dns.ListenAndServe(s.config.DnsAddr, s.dnsUDPclient.Net, mux); err != nil { log.Fatalf("skydns: %s", err) } }() dnsReadyMsg(s.config.DnsAddr, s.dnsUDPclient.Net) s.group.Wait() return nil }
func (d *DNSServer) createMux(client *dns.Client, defaultMaxResponseSize int) *dns.ServeMux { m := dns.NewServeMux() m.HandleFunc(d.domain, d.handleLocal(defaultMaxResponseSize)) m.HandleFunc(reverseDNSdomain, d.handleReverse(client, defaultMaxResponseSize)) m.HandleFunc(topDomain, d.handleRecursive(client, defaultMaxResponseSize)) return m }
func (srv *DNSServer) ListenAndServe() error { if srv.GetStore() == nil { panic("missing Store") } if srv.Domain == "" { srv.Domain = dnsDomain } if err := srv.validateRecursors(); err != nil { return err } api := dnsAPI{srv} mux := dns.NewServeMux() mux.HandleFunc(srv.Domain, api.ServiceLookup) if len(srv.Recursors) > 0 { mux.HandleFunc(".", api.Recurse) } errors := make(chan error, 4) done := func() { errors <- nil } if srv.UDPAddr != "" { l, err := reuseport.NewReusablePortPacketConn("udp4", srv.UDPAddr) if err != nil { return err } srv.UDPAddr = l.(*net.UDPConn).LocalAddr().String() server := &dns.Server{ Net: "udp", PacketConn: l, Handler: mux, NotifyStartedFunc: done, } go func() { errors <- server.ActivateAndServe() }() srv.servers = append(srv.servers, server) } if srv.TCPAddr != "" { l, err := keepalive.ReusableListen("tcp4", srv.TCPAddr) if err != nil { return err } srv.TCPAddr = l.Addr().String() server := &dns.Server{ Net: "tcp", Listener: l, Handler: mux, NotifyStartedFunc: done, } go func() { errors <- server.ActivateAndServe() }() srv.servers = append(srv.servers, server) } for range srv.servers { if err := <-errors; err != nil { return err } } return nil }
// Start the mDNS server func (s *MDNSServer) Start(ifi *net.Interface) (err error) { // skip double initialization if s.running { return nil } // This is a bit of a kludge - per the RFC we should send responses from 5353, but that doesn't seem to work s.sendconn, err = net.ListenUDP("udp4", &net.UDPAddr{IP: net.IPv4zero, Port: 0}) if err != nil { return err } conn, err := LinkLocalMulticastListener(ifi) if err != nil { return err } if ifi == nil { s.localAddrs, err = net.InterfaceAddrs() } else { s.localAddrs, err = ifi.Addrs() } if err != nil { return err } handleLocal := s.makeHandler(dns.TypeA, func(zone ZoneLookup, r *dns.Msg, q *dns.Question) *dns.Msg { if ips, err := zone.LookupName(q.Name); err == nil { return makeAddressReply(r, q, ips) } return nil }) handleReverse := s.makeHandler(dns.TypePTR, func(zone ZoneLookup, r *dns.Msg, q *dns.Question) *dns.Msg { if names, err := zone.LookupInaddr(q.Name); err == nil { return makePTRReply(r, q, names) } return nil }) mux := dns.NewServeMux() mux.HandleFunc(s.zone.Domain(), handleLocal) mux.HandleFunc(RDNSDomain, handleReverse) s.srv = &dns.Server{ Listener: nil, PacketConn: conn, Handler: mux, } go s.srv.ActivateAndServe() s.running = true return err }
// Run is a blocking operation that starts the server listening on the DNS ports. func (s *server) Run() error { mux := dns.NewServeMux() mux.Handle(".", s) s.group.Add(2) go runDNSServer(s.group, mux, "tcp", s.config.DnsAddr, s.config.ReadTimeout) go runDNSServer(s.group, mux, "udp", s.config.DnsAddr, s.config.ReadTimeout) s.group.Wait() return nil }
func (d *DNSServer) createMux(client *dns.Client, defaultMaxResponseSize int) *dns.ServeMux { m := dns.NewServeMux() h := &handler{ DNSServer: d, maxResponseSize: defaultMaxResponseSize, client: client, } m.HandleFunc(d.domain, h.handleLocal) m.HandleFunc(reverseDNSdomain, h.handleReverse) m.HandleFunc(topDomain, h.handleRecursive) return m }
func (s *Server) Start() error { s.mux = dns.NewServeMux() s.mux.Handle(".", s.engine) s.wgStart.Add(2) s.udpListener = s.runListener("udp") s.tcpListener = s.runListener("tcp") s.wgStart.Wait() log.Info("Listeners started") return nil }
// Run is a blocking operation that starts the server listening on the DNS ports. func (s *server) Run() error { mux := dns.NewServeMux() mux.Handle(".", s) s.group.Add(2) go runDNSServer(s.group, mux, "tcp", s.config.DnsAddr, s.config.ReadTimeout) go runDNSServer(s.group, mux, "udp", s.config.DnsAddr, s.config.ReadTimeout) s.config.log.Printf("connected to etcd cluster at %s", machines) s.group.Wait() return nil }
// Newserver returns a new Server. func NewServer(members []string, domain string, dnsAddr string, httpAddr string, dataDir string, rt, wt time.Duration, secret string, nameservers []string, roundrobin bool, tlskey string, tlspem string) (s *Server) { s = &Server{ members: members, domain: strings.ToLower(domain), domainLabels: dns.CountLabel(dns.Fqdn(domain)), dnsAddr: dnsAddr, httpAddr: httpAddr, readTimeout: rt, writeTimeout: wt, router: mux.NewRouter(), registry: registry.New(), dataDir: dataDir, dnsHandler: dns.NewServeMux(), waiter: new(sync.WaitGroup), secret: secret, nameservers: nameservers, roundrobin: roundrobin, tlskey: tlskey, tlspem: tlspem, } if _, err := os.Stat(s.dataDir); os.IsNotExist(err) { log.Fatal("Data directory does not exist: ", dataDir) return } // DNS s.dnsHandler.Handle(".", s) authWrapper := s.authHTTPWrapper // API Routes s.router.HandleFunc("/skydns/services/{uuid}", authWrapper(s.addServiceHTTPHandler)).Methods("PUT") s.router.HandleFunc("/skydns/services/{uuid}", authWrapper(s.getServiceHTTPHandler)).Methods("GET") s.router.HandleFunc("/skydns/services/{uuid}", authWrapper(s.removeServiceHTTPHandler)).Methods("DELETE") s.router.HandleFunc("/skydns/services/{uuid}", authWrapper(s.updateServiceHTTPHandler)).Methods("PATCH") s.router.HandleFunc("/skydns/callbacks/{uuid}", authWrapper(s.addCallbackHTTPHandler)).Methods("PUT") // External API Routes // /skydns/services #list all services s.router.HandleFunc("/skydns/services/", authWrapper(s.getServicesHTTPHandler)).Methods("GET") // /skydns/regions #list all regions s.router.HandleFunc("/skydns/regions/", authWrapper(s.getRegionsHTTPHandler)).Methods("GET") // /skydns/environnments #list all environments s.router.HandleFunc("/skydns/environments/", authWrapper(s.getEnvironmentsHTTPHandler)).Methods("GET") // Raft Routes s.router.HandleFunc("/raft/join", s.joinHandler).Methods("POST") return }
// Run is a blocking operation that starts the server listening on the DNS ports func (s *server) Run() error { var ( group = &sync.WaitGroup{} mux = dns.NewServeMux() ) mux.Handle(".", s) group.Add(2) go runDNSServer(group, mux, "tcp", s.config.DnsAddr, 0, s.config.WriteTimeout, s.config.ReadTimeout) go runDNSServer(group, mux, "udp", s.config.DnsAddr, 0, s.config.WriteTimeout, s.config.ReadTimeout) group.Wait() return nil }
func (s *Server) Run() (err error) { hndlr := handler.NewHandler(s.Timeout, s.Interval) tcpHandler := dns.NewServeMux() tcpHandler.HandleFunc(".", hndlr.HandleTcp) tcpServer := &dns.Server{ Addr: s.Addr(), Net: "tcp", Handler: tcpHandler, ReadTimeout: s.Timeout, WriteTimeout: s.Timeout, } go func() { err := tcpServer.ListenAndServe() if err != nil { panic(err) } }() udpHandler := dns.NewServeMux() udpHandler.HandleFunc(".", hndlr.HandleUdp) udpServer := &dns.Server{ Addr: s.Addr(), Net: "udp", Handler: udpHandler, ReadTimeout: s.Timeout, WriteTimeout: s.Timeout, } go func() { err := udpServer.ListenAndServe() if err != nil { panic(err) } }() return }
// Newserver returns a new server. // TODO(miek): multiple ectdAddrs func NewServer(domain, dnsAddr string, nameservers []string, etcdAddr string) *server { s := &server{ domain: dns.Fqdn(strings.ToLower(domain)), domainLabels: dns.CountLabel(dns.Fqdn(domain)), DnsAddr: dnsAddr, client: etcd.NewClient([]string{etcdAddr}), dnsHandler: dns.NewServeMux(), waiter: new(sync.WaitGroup), nameservers: nameservers, } // DNS s.dnsHandler.Handle(".", s) return s }
// Run is a blocking operation that starts the server listening on the DNS ports. func (s *server) Run() error { mux := dns.NewServeMux() mux.Handle(".", s) s.group.Add(2) go runDNSServer(s.group, mux, "tcp", s.config.DnsAddr, s.config.ReadTimeout) go runDNSServer(s.group, mux, "udp", s.config.DnsAddr, s.config.ReadTimeout) if s.config.DNSSEC == "" { s.config.log.Printf("ready for queries on %s for %s [rcache %d - ttl %d]", s.config.Domain, s.config.DnsAddr, s.config.RCache, s.config.RCacheTtl) } else { s.config.log.Printf("ready for queries on %s for %s [rcache %d - ttl %d], signing with %s [scache %d]", s.config.Domain, s.config.DnsAddr, s.config.RCache, s.config.RCacheTtl, s.config.DNSSEC, s.config.SCache) } s.group.Wait() return nil }
func NewDNSServer(c *Config) *DNSServer { s := &DNSServer{ config: c, services: make(map[string]*Service), lock: &sync.RWMutex{}, } mux := dns.NewServeMux() mux.HandleFunc(c.domain[len(c.domain)-1]+".", s.handleRequest) mux.HandleFunc("arpa.", s.handleRequest) mux.HandleFunc(".", s.handleOrForward) s.server = &dns.Server{Addr: c.dnsAddr, Net: "udp", Handler: mux} return s }
func NewDNSServer(c *Config) *DNSServer { s := &DNSServer{ config: c, services: make(map[string]*Service), lock: &sync.RWMutex{}, } s.mux = dns.NewServeMux() s.mux.HandleFunc(c.domain.String()+".", s.handleRequest) s.mux.HandleFunc("in-addr.arpa.", s.handleReverseRequest) s.mux.HandleFunc(".", s.handleForward) s.server = &dns.Server{Addr: c.dnsAddr, Net: "udp", Handler: s.mux} return s }
// New creates a DnsServer ready to serve queries for the specified domain on // the given host:port using the specified DNS Resource Record table as the // source of truth. func New(domain, addr string, rr rrstore.RRReader, recurse bool, nameservers []string) *DnsServer { d := &DnsServer{rr: rr, recurse: recurse, nameservers: nameservers} mux := dns.NewServeMux() mux.HandleFunc(".", d.handleExternal) mux.HandleFunc(dns.Fqdn(domain), d.handleDomain) d.Server = &dns.Server{ Addr: addr, Net: "udp", Handler: mux, } d.Server.NotifyStartedFunc = func() { log.Printf("DNS server started listening at %s", d.Server.Addr) } return d }
// Newserver returns a new Server. func NewServer(members []string, domain string, dnsAddr string, httpAddr string, dataDir string, rt, wt time.Duration, secret string) (s *Server) { s = &Server{ members: members, domain: domain, dnsAddr: dnsAddr, httpAddr: httpAddr, readTimeout: rt, writeTimeout: wt, router: mux.NewRouter(), registry: registry.New(), dataDir: dataDir, dnsHandler: dns.NewServeMux(), waiter: new(sync.WaitGroup), secret: secret, } if _, err := os.Stat(s.dataDir); os.IsNotExist(err) { log.Fatal("Data directory does not exist: ", dataDir) return } // DNS s.dnsHandler.Handle(".", s) // API Routes s.router.HandleFunc("/skydns/services/{uuid}", s.addServiceHTTPHandler).Methods("PUT") s.router.HandleFunc("/skydns/services/{uuid}", s.getServiceHTTPHandler).Methods("GET") s.router.HandleFunc("/skydns/services/{uuid}", s.removeServiceHTTPHandler).Methods("DELETE") s.router.HandleFunc("/skydns/services/{uuid}", s.updateServiceHTTPHandler).Methods("PATCH") // External API Routes // /skydns/services #list all services s.router.HandleFunc("/skydns/services/", s.getServicesHTTPHandler).Methods("GET") // /skydns/regions #list all regions s.router.HandleFunc("/skydns/regions/", s.getRegionsHTTPHandler).Methods("GET") // /skydns/environnments #list all environments s.router.HandleFunc("/skydns/environments/", s.getEnvironmentsHTTPHandler).Methods("GET") // Raft Routes s.router.HandleFunc("/raft/join", s.joinHandler).Methods("POST") return }
func NewService(c Config) *Service { mux := dns.NewServeMux() if !strings.HasSuffix(c.Domain, ".") { c.Domain += "." } if !strings.HasSuffix(c.Mbox, ".") { c.Mbox += "." } if !strings.HasSuffix(c.Host, ".") { c.Host += "." } s := &Service{ Config: &c, logger: log.New(os.Stderr, "[named] ", log.LstdFlags), server: &dns.Server{Addr: c.Addr, Net: strings.ToLower(c.Net), Handler: mux}, } mux.HandleFunc(c.Domain, s.handle) return s }
// Create a multiplexer for requests // We must create two DNS request multiplexers, depending on the protocol used by // clients (as we use the same protocol for asking upstream servers) func (s *DNSServer) createMux(proto dnsProtocol) *dns.ServeMux { failFallback := func(w dns.ResponseWriter, r *dns.Msg) { w.WriteMsg(makeDNSFailResponse(r)) } notUsHandler := s.notUsHandler(proto) notUsFallback := func(w dns.ResponseWriter, r *dns.Msg) { Info.Printf("[dns msgid %d] -> sending to fallback server", r.MsgHdr.Id) notUsHandler(w, r) } // create the multiplexer m := dns.NewServeMux() m.HandleFunc(s.Zone.Domain(), s.localHandler(proto, "Query", dns.TypeA, s.Zone.DomainLookupName, makeAddressReply, s.Zone.ObserveName, failFallback)) m.HandleFunc(RDNSDomain, s.localHandler(proto, "Reverse query", dns.TypePTR, s.Zone.DomainLookupInaddr, makePTRReply, s.Zone.ObserveInaddr, notUsFallback)) m.HandleFunc(".", s.notUsHandler(proto)) return m }
// makeRecursor creates a generic DNS server which always returns // the provided reply. This is useful for mocking a DNS recursor with // an expected result. func makeRecursor(t *testing.T, answer []dns.RR) *dns.Server { dnsConf := nextConfig() dnsAddr := fmt.Sprintf("%s:%d", dnsConf.Addresses.DNS, dnsConf.Ports.DNS) mux := dns.NewServeMux() mux.HandleFunc(".", func(resp dns.ResponseWriter, msg *dns.Msg) { ans := &dns.Msg{Answer: answer[:]} ans.SetReply(msg) if err := resp.WriteMsg(ans); err != nil { t.Fatalf("err: %s", err) } }) server := &dns.Server{ Addr: dnsAddr, Net: "udp", Handler: mux, } go server.ListenAndServe() return server }
// startDNSServer starts a DNS server with a given handler function on a random port. // Returns the Server object itself as well as the net.Addr corresponding to the server port. func startDNSServer(protocol string, handler func(dns.ResponseWriter, *dns.Msg)) (*dns.Server, net.Addr) { h := dns.NewServeMux() h.HandleFunc(".", handler) server := &dns.Server{Addr: ":0", Net: protocol, Handler: h} go server.ListenAndServe() // Wait until PacketConn becomes available, but give up after 1 second. for i := 0; server.PacketConn == nil && i < 200; i++ { if protocol == "tcp" && server.Listener != nil { break } if protocol == "udp" && server.PacketConn != nil { break } time.Sleep(5 * time.Millisecond) } if protocol == "tcp" { return server, server.Listener.Addr() } return server, server.PacketConn.LocalAddr() }
func (s *DNS) Run() { s.cache.records = make(map[string]*Record) mux := dns.NewServeMux() bind := s.bind + ":" + strconv.Itoa(s.port) srvUDP := &dns.Server{ Addr: bind, Net: "udp", Handler: mux, } srvTCP := &dns.Server{ Addr: bind, Net: "tcp", Handler: mux, } mux.HandleFunc(s.domain, s.handleDNSInternal) mux.HandleFunc("in-addr.arpa.", s.handleReverseDNSLookup) mux.HandleFunc(".", s.handleDNSExternal) go func() { log.Printf("Binding UDP listener to %s", bind) err := srvUDP.ListenAndServe() if err != nil { log.Fatal(err) } }() go func() { log.Printf("Binding TCP listener to %s", bind) err := srvTCP.ListenAndServe() if err != nil { log.Fatal(err) } }() }
// Run is a blocking operation that starts the server listening on the DNS ports. func (s *server) Run() error { mux := dns.NewServeMux() mux.Handle(".", s) s.group.Add(2) go s.run(mux, "tcp") go s.run(mux, "udp") // Healthchecking. log.Printf("enabling health checking") go func() { for { time.Sleep(5 * 1e9) s.HealthCheck() } }() // Set a Watch and check for changes. log.Printf("setting watch") ch := make(chan *etcd.Response) go func() { go s.client.Watch("/dnsrouter", 0, true, ch, s.stop) for { select { case n := <-ch: s.Update(n) } } }() log.Printf("getting initial list") n, err := s.client.Get("/dnsrouter/", false, true) if err == nil { s.Update(n) } log.Printf("ready for queries") s.group.Wait() return nil }
// Start server. func (s *Server) Start() error { s.mux = dns.NewServeMux() s.udp = &dns.Server{ Addr: s.Bind, Net: "udp", Handler: s.mux, UDPSize: 65535, } s.tcp = &dns.Server{ Addr: s.Bind, Net: "tcp", Handler: s.mux, } for _, domain := range s.Domains { s.mux.Handle(dns.Fqdn(domain.Name), &Domain{domain}) } s.mux.Handle(".", &RandomUpstream{s.Upstream}) go func() { if err := s.udp.ListenAndServe(); err != nil { log.Fatalf("[error] failed to bind udp server: %v", err) } }() go func() { if err := s.tcp.ListenAndServe(); err != nil { log.Fatalf("[error] failed to bind tcp server: %v", err) } }() return nil }
func TestRecursiveCompress(t *testing.T) { const ( hostname = "foo.example." maxSize = 512 ) // Construct a response that is >512 when uncompressed, <512 when compressed response := dns.Msg{} response.Authoritative = true response.Answer = []dns.RR{} header := dns.RR_Header{ Name: hostname, Rrtype: dns.TypeA, Class: dns.ClassINET, Ttl: 10, } for response.Len() <= maxSize { ip := address.Address(rand.Uint32()).IP4() response.Answer = append(response.Answer, &dns.A{Hdr: header, A: ip}) } response.Compress = true require.True(t, response.Len() <= maxSize) // A dns server that returns the above response var gotRequest = make(chan struct{}, 1) handleRecursive := func(w dns.ResponseWriter, req *dns.Msg) { gotRequest <- struct{}{} require.Equal(t, req.Question[0].Name, hostname) response.SetReply(req) err := w.WriteMsg(&response) require.Nil(t, err) } mux := dns.NewServeMux() mux.HandleFunc(topDomain, handleRecursive) udpListener, err := net.ListenPacket("udp", "0.0.0.0:0") require.Nil(t, err) udpServer := &dns.Server{PacketConn: udpListener, Handler: mux} udpServerPort := udpListener.LocalAddr().(*net.UDPAddr).Port go udpServer.ActivateAndServe() defer udpServer.Shutdown() // The weavedns server, pointed at the above server dnsserver, _, udpPort, _ := startServer(t, &dns.ClientConfig{ Servers: []string{"127.0.0.1"}, Port: strconv.Itoa(udpServerPort), Ndots: 1, Timeout: 5, Attempts: 2, }) defer dnsserver.Stop() // Now do lookup, check its what we expected. // NB this doesn't really test golang's resolver behaves correctly, as I can't see // a way to point golangs resolver at a specific hosts. req := new(dns.Msg) req.Id = dns.Id() req.RecursionDesired = true req.Question = make([]dns.Question, 1) req.Question[0] = dns.Question{ Name: hostname, Qtype: dns.TypeA, Qclass: dns.ClassINET, } c := new(dns.Client) res, _, err := c.Exchange(req, fmt.Sprintf("127.0.0.1:%d", udpPort)) require.Nil(t, err) require.True(t, len(gotRequest) > 0) require.True(t, res.Len() > maxSize) }
// Run is a blocking operation that starts the server listening on the DNS ports. func (s *server) Run() error { mux := dns.NewServeMux() mux.Handle(".", s) dnsReadyMsg := func(addr, net string) { if s.config.DNSSEC == "" { log.Printf("skydns: ready for queries on %s for %s://%s [rcache %d]", s.config.Domain, net, addr, s.config.RCache) } else { log.Printf("skydns: ready for queries on %s for %s://%s [rcache %d], signing with %s [scache %d]", s.config.Domain, net, addr, s.config.RCache, s.config.DNSSEC, s.config.SCache) } } if s.config.Systemd { packetConns, err := activation.PacketConns(false) if err != nil { return err } listeners, err := activation.Listeners(true) if err != nil { return err } if len(packetConns) == 0 && len(listeners) == 0 { return fmt.Errorf("no UDP or TCP sockets supplied by systemd") } for _, p := range packetConns { if u, ok := p.(*net.UDPConn); ok { s.group.Add(1) go func() { defer s.group.Done() if err := dns.ActivateAndServe(nil, u, mux); err != nil { log.Fatalf("skydns: %s", err) } }() dnsReadyMsg(u.LocalAddr().String(), "udp") } } for _, l := range listeners { if t, ok := l.(*net.TCPListener); ok { s.group.Add(1) go func() { defer s.group.Done() if err := dns.ActivateAndServe(t, nil, mux); err != nil { log.Fatalf("skydns: %s", err) } }() dnsReadyMsg(t.Addr().String(), "tcp") } } } else { s.group.Add(1) go func() { defer s.group.Done() if err := dns.ListenAndServe(s.config.DnsAddr, "tcp", mux); err != nil { log.Fatalf("skydns: %s", err) } }() dnsReadyMsg(s.config.DnsAddr, "tcp") s.group.Add(1) go func() { defer s.group.Done() if err := dns.ListenAndServe(s.config.DnsAddr, "udp", mux); err != nil { log.Fatalf("skydns: %s", err) } }() dnsReadyMsg(s.config.DnsAddr, "udp") } s.group.Wait() return nil }
// NewDNSServer starts a new DNS server to provide an agent interface func NewDNSServer(agent *Agent, config *DNSConfig, logOutput io.Writer, domain, bind, recursor string) (*DNSServer, error) { // Make sure domain is FQDN domain = dns.Fqdn(domain) // Construct the DNS components mux := dns.NewServeMux() // Setup the servers server := &dns.Server{ Addr: bind, Net: "udp", Handler: mux, UDPSize: 65535, } serverTCP := &dns.Server{ Addr: bind, Net: "tcp", Handler: mux, } // Create the server srv := &DNSServer{ agent: agent, config: config, dnsHandler: mux, dnsServer: server, dnsServerTCP: serverTCP, domain: domain, recursor: recursor, logger: log.New(logOutput, "", log.LstdFlags), } // Register mux handlers, always handle "consul." mux.HandleFunc(domain, srv.handleQuery) if domain != consulDomain { mux.HandleFunc(consulDomain, srv.handleTest) } if recursor != "" { recursor, err := recursorAddr(recursor) if err != nil { return nil, fmt.Errorf("Invalid recursor address: %v", err) } srv.recursor = recursor mux.HandleFunc(".", srv.handleRecurse) } // Async start the DNS Servers, handle a potential error errCh := make(chan error, 1) go func() { err := server.ListenAndServe() srv.logger.Printf("[ERR] dns: error starting udp server: %v", err) errCh <- err }() errChTCP := make(chan error, 1) go func() { err := serverTCP.ListenAndServe() srv.logger.Printf("[ERR] dns: error starting tcp server: %v", err) errChTCP <- err }() // Check the server is running, do a test lookup checkCh := make(chan error, 1) go func() { // This is jank, but we have no way to edge trigger on // the start of our server, so we just wait and hope it is up. time.Sleep(50 * time.Millisecond) m := new(dns.Msg) m.SetQuestion(testQuery, dns.TypeANY) c := new(dns.Client) in, _, err := c.Exchange(m, bind) if err != nil { checkCh <- err return } if len(in.Answer) == 0 { checkCh <- fmt.Errorf("no response to test message") return } close(checkCh) }() // Wait for either the check, listen error, or timeout select { case e := <-errCh: return srv, e case e := <-errChTCP: return srv, e case e := <-checkCh: return srv, e case <-time.After(time.Second): return srv, fmt.Errorf("timeout setting up DNS server") } return srv, nil }