From 19da02b9bfbbf7f154032daea46dd4ba37d6284a Mon Sep 17 00:00:00 2001
From: ale <ale@incal.net>
Date: Fri, 12 Apr 2019 11:48:57 +0100
Subject: [PATCH] Properly stop all services on error, and improve logging

---
 node/dns.go    | 18 ++++++++++++------
 node/http.go   | 24 +++++++++++++++---------
 node/server.go | 16 +++++++++++-----
 node/status.go |  2 ++
 4 files changed, 40 insertions(+), 20 deletions(-)

diff --git a/node/dns.go b/node/dns.go
index b1f543f2..74e4fbcd 100644
--- a/node/dns.go
+++ b/node/dns.go
@@ -203,16 +203,22 @@ func ednsFromRequest(req, m *dns.Msg) {
 // Wrapper to make the dns.Server match the genericServer interface.
 type dnsServer struct {
 	*dns.Server
+	name string
 }
 
-func newDNSServer(addr, proto string, h dns.Handler) *dnsServer {
-	return &dnsServer{&dns.Server{
-		Addr:    addr,
-		Net:     proto,
-		Handler: h,
-	}}
+func newDNSServer(name, addr, proto string, h dns.Handler) *dnsServer {
+	return &dnsServer{
+		Server: &dns.Server{
+			Addr:    addr,
+			Net:     proto,
+			Handler: h,
+		},
+		name: name,
+	}
 }
 
+func (s *dnsServer) Name() string { return s.name }
+
 func (s *dnsServer) Serve() error {
 	return s.Server.ListenAndServe()
 }
diff --git a/node/http.go b/node/http.go
index 9058a84b..97a7dc6a 100644
--- a/node/http.go
+++ b/node/http.go
@@ -246,19 +246,25 @@ func withLocalhost(h http.Handler) http.Handler {
 // Wrapper to make an http.Server match the genericServer interface.
 type httpServer struct {
 	*http.Server
+	name string
 }
 
-func newHTTPServer(addr string, h http.Handler) *httpServer {
-	return &httpServer{&http.Server{
-		Addr:              addr,
-		Handler:           h,
-		ReadTimeout:       10 * time.Second,
-		ReadHeaderTimeout: 3 * time.Second,
-		WriteTimeout:      10 * time.Second,
-		IdleTimeout:       30 * time.Second,
-	}}
+func newHTTPServer(name, addr string, h http.Handler) *httpServer {
+	return &httpServer{
+		Server: &http.Server{
+			Addr:              addr,
+			Handler:           h,
+			ReadTimeout:       10 * time.Second,
+			ReadHeaderTimeout: 3 * time.Second,
+			WriteTimeout:      10 * time.Second,
+			IdleTimeout:       30 * time.Second,
+		},
+		name: name,
+	}
 }
 
+func (s *httpServer) Name() string { return s.name }
+
 func (s *httpServer) Serve() error {
 	err := s.Server.ListenAndServe()
 	if err == http.ErrServerClosed {
diff --git a/node/server.go b/node/server.go
index 5a265de8..a9d53b44 100644
--- a/node/server.go
+++ b/node/server.go
@@ -2,6 +2,7 @@ package node
 
 import (
 	"fmt"
+	"log"
 	"net"
 	"strconv"
 	"sync"
@@ -9,6 +10,7 @@ import (
 
 // A genericServer is just something that can be started and stopped.
 type genericServer interface {
+	Name() string
 	Serve() error
 	Stop()
 }
@@ -33,10 +35,14 @@ func buildServer(servers ...genericServer) *Server {
 		ms.wg.Add(1)
 		go func(s genericServer) {
 			defer ms.wg.Done()
+			log.Printf("starting network service: %s", s.Name())
 			err := s.Serve()
 			if err != nil {
+				werr := fmt.Errorf("%s: %v", s.Name(), err)
 				select {
-				case ms.errCh <- err:
+				case ms.errCh <- werr:
+					// First error, stop all other services.
+					ms.Stop()
 				default:
 				}
 			}
@@ -78,13 +84,13 @@ func NewServer(n *Node, domain string, nameservers []string, publicAddrs []net.I
 
 	servers := []genericServer{
 		newStatusServer(mkaddr(peerAddr, gossipPort), n.statusMgr),
-		newHTTPServer(fmt.Sprintf(":%d", metricsPort), newMetricsHandler()),
+		newHTTPServer("metrics", fmt.Sprintf(":%d", metricsPort), newMetricsHandler()),
 	}
 	for _, ip := range publicAddrs {
 		servers = append(servers,
-			newHTTPServer(mkaddr(ip, httpPort), httpHandler),
-			newDNSServer(mkaddr(ip, dnsPort), "udp", dnsHandler),
-			newDNSServer(mkaddr(ip, dnsPort), "tcp", dnsHandler),
+			newHTTPServer("main", mkaddr(ip, httpPort), httpHandler),
+			newDNSServer("dns(udp)", mkaddr(ip, dnsPort), "udp", dnsHandler),
+			newDNSServer("dns(tcp)", mkaddr(ip, dnsPort), "tcp", dnsHandler),
 		)
 	}
 	return buildServer(servers...)
diff --git a/node/status.go b/node/status.go
index 365456d8..014e5cf3 100644
--- a/node/status.go
+++ b/node/status.go
@@ -185,6 +185,8 @@ func newStatusServer(addr string, statusMgr *statusManager) *statusServer {
 	}
 }
 
+func (s *statusServer) Name() string { return "status" }
+
 func (s *statusServer) Serve() error {
 	l, err := net.Listen("tcp", s.addr)
 	if err != nil {
-- 
GitLab