From 77fb2b0aa136ffca08a779c721a6375040b7e87d Mon Sep 17 00:00:00 2001
From: ale <ale@incal.net>
Date: Tue, 7 Jan 2020 20:55:42 +0000
Subject: [PATCH] DNS listening address are not necessarily public IPs

It is best to just make the DNS server listen on all non-loopback IP
addresses from all interfaces. The loopback exclusion is just to
integrate nicely with an eventual DNS cache running on the same host.
---
 cmd/radiod/radiod.go | 27 +++++++++++++++++++++++++--
 node/server.go       |  6 +++---
 2 files changed, 28 insertions(+), 5 deletions(-)

diff --git a/cmd/radiod/radiod.go b/cmd/radiod/radiod.go
index 54b24c9d..91245042 100644
--- a/cmd/radiod/radiod.go
+++ b/cmd/radiod/radiod.go
@@ -52,6 +52,27 @@ func shortHostname() string {
 	return hostname
 }
 
+// Returns the list of all non-loopback addresses (IPv4 and IPv6) for
+// all interfaces.
+func nonLocalAddrs() []net.IP {
+	var ips []net.IP
+
+	// nolint: errcheck
+	interfaces, _ := net.Interfaces()
+	for _, intf := range interfaces {
+		addrs, _ := intf.Addrs()
+		for _, addr := range addrs {
+			ip, _, err := net.ParseCIDR(addr.String())
+			if err != nil || ip.IsLoopback() {
+				continue
+			}
+			ips = append(ips, ip)
+		}
+	}
+
+	return ips
+}
+
 func main() {
 	log.SetFlags(0)
 	flag.Parse()
@@ -136,8 +157,10 @@ func main() {
 		log.Fatalf("could not initialize node: %v", err)
 	}
 
-	// Start all the network services.
-	srv := node.NewServer(n, *domain, strings.Split(*nameservers, ","), *publicIPs, *peerIP, *httpPort, *dnsPort, *gossipPort, autoradio.IcecastPort, *metricsPort)
+	// Start all the network services. DNS will listen on all
+	// non-loopback addresses on all interfaces, to let people run
+	// a loopback cache if necessary.
+	srv := node.NewServer(n, *domain, strings.Split(*nameservers, ","), nonLocalAddrs(), *peerIP, *httpPort, *dnsPort, *gossipPort, autoradio.IcecastPort, *metricsPort)
 
 	// Wait until the Node and the Server terminate. A failure in
 	// either the network services or the Node itself should cause
diff --git a/node/server.go b/node/server.go
index b9fc6a43..158f24ed 100644
--- a/node/server.go
+++ b/node/server.go
@@ -80,10 +80,10 @@ func (s *Server) Wait() error {
 // build all the necessary addr/port combinations.
 //
 // The main http handler will bind on all available interfaces. The
-// DNS servers will bind only to the publicAddrs (both TCP and
+// DNS servers will bind only to the dnsAddrs (both TCP and
 // UDP). The metrics and the status services, which are internal, will
 // bind on peerAddr.
-func NewServer(n *Node, domain string, nameservers []string, publicAddrs []net.IP, peerAddr net.IP, httpPort, dnsPort, gossipPort, icecastPort, metricsPort int) *Server {
+func NewServer(n *Node, domain string, nameservers []string, dnsAddrs []net.IP, peerAddr net.IP, httpPort, dnsPort, gossipPort, icecastPort, metricsPort int) *Server {
 	httpHandler := newHTTPHandler(n, icecastPort, domain)
 	dnsHandler := newDNSHandler(n, domain, nameservers)
 
@@ -92,7 +92,7 @@ func NewServer(n *Node, domain string, nameservers []string, publicAddrs []net.I
 		newHTTPServer("main", fmt.Sprintf(":%d", httpPort), httpHandler),
 		newHTTPServer("metrics", fmt.Sprintf(":%d", metricsPort), newMetricsHandler()),
 	}
-	for _, ip := range publicAddrs {
+	for _, ip := range dnsAddrs {
 		servers = append(servers,
 			newDNSServer("dns(udp)", mkaddr(ip, dnsPort), "udp", dnsHandler),
 			newDNSServer("dns(tcp)", mkaddr(ip, dnsPort), "tcp", dnsHandler),
-- 
GitLab