diff --git a/cmd/cloudflared/main.go b/cmd/cloudflared/main.go index 4a1a3dd0..878de28e 100644 --- a/cmd/cloudflared/main.go +++ b/cmd/cloudflared/main.go @@ -425,7 +425,7 @@ func startServer(c *cli.Context) { var wg sync.WaitGroup errC := make(chan error) connectedSignal := make(chan struct{}) - wg.Add(2) + dnsReadySignal := make(chan struct{}) // If the user choose to supply all options through env variables, // c.NumFlags() == 0 && c.NArg() == 0. For cloudflared to work, the user needs to at @@ -454,23 +454,16 @@ func startServer(c *cli.Context) { } } - if isAutoupdateEnabled(c) { - if initUpdate() { - return - } - Log.Infof("Autoupdate frequency is set to %v", c.Duration("autoupdate-freq")) - go autoupdate(c.Duration("autoupdate-freq"), shutdownC) - } - if c.IsSet("proxy-dns") { wg.Add(1) listener, err := tunneldns.CreateListener(c.String("proxy-dns-address"), uint16(c.Uint("proxy-dns-port")), c.StringSlice("proxy-dns-upstream")) if err != nil { + close(dnsReadySignal) listener.Stop() Log.WithError(err).Fatal("Cannot create the DNS over HTTPS proxy server") } go func() { - err := listener.Start() + err := listener.Start(dnsReadySignal) if err != nil { Log.WithError(err).Fatal("Cannot start the DNS over HTTPS proxy server") } else { @@ -479,14 +472,26 @@ func startServer(c *cli.Context) { listener.Stop() wg.Done() }() + } else { + close(dnsReadySignal) + } - // Serve DNS proxy stand-alone if no hostname or tag or app is going to run - if !c.IsSet("hostname") && !c.IsSet("tag") && !c.IsSet("hello-world") { - go writePidFile(connectedSignal, c.String("pidfile")) - close(connectedSignal) - runServer(c, &wg, errC, shutdownC) + if isAutoupdateEnabled(c) { + // Wait for proxy-dns to come up (if used) + <-dnsReadySignal + if initUpdate() { return } + Log.Infof("Autoupdate frequency is set to %v", c.Duration("autoupdate-freq")) + go autoupdate(c.Duration("autoupdate-freq"), shutdownC) + } + + // Serve DNS proxy stand-alone if no hostname or tag or app is going to run + if c.IsSet("proxy-dns") && (!c.IsSet("hostname") && !c.IsSet("tag") && !c.IsSet("hello-world")) { + go writePidFile(connectedSignal, c.String("pidfile")) + close(connectedSignal) + runServer(c, &wg, errC, shutdownC) + return } hostname, err := validation.ValidateHostname(c.String("hostname")) @@ -601,6 +606,7 @@ If you don't have a certificate signed by Cloudflare, run the command: } go writePidFile(connectedSignal, c.String("pidfile")) + wg.Add(1) go func() { errC <- origin.StartTunnelDaemon(tunnelConfig, shutdownC, connectedSignal) wg.Done() @@ -610,6 +616,7 @@ If you don't have a certificate signed by Cloudflare, run the command: } func runServer(c *cli.Context, wg *sync.WaitGroup, errC chan error, shutdownC chan struct{}) { + wg.Add(1) metricsListener, err := listeners.Listen("tcp", c.String("metrics")) if err != nil { Log.WithError(err).Fatal("Error opening metrics server listener") diff --git a/tunneldns/tunnel.go b/tunneldns/tunnel.go index 145f1285..efd1229d 100644 --- a/tunneldns/tunnel.go +++ b/tunneldns/tunnel.go @@ -40,11 +40,13 @@ func Run(c *cli.Context) error { } // Try to start the server - err = listener.Start() + readySignal := make(chan struct{}) + err = listener.Start(readySignal) if err != nil { log.WithError(err).Errorf("Failed to start the listeners") return listener.Stop() } + <-readySignal // Wait for signal signals := make(chan os.Signal, 10) @@ -74,7 +76,8 @@ func createConfig(address string, port uint16, p plugin.Handler) *dnsserver.Conf } // Start blocks for serving requests -func (l *Listener) Start() error { +func (l *Listener) Start(readySignal chan struct{}) error { + defer close(readySignal) log.WithField("addr", l.server.Address()).Infof("Starting DNS over HTTPS proxy server") // Start UDP listener