mirror of
https://github.com/Control-D-Inc/ctrld.git
synced 2026-08-10 13:20:33 +02:00
cmd/ctrld: spawn RFC1918 listeners if listen on 127.0.0.1:53
This commit is contained in:
+35
-9
@@ -7,6 +7,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
|
"net/netip"
|
||||||
"os"
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
@@ -17,6 +18,7 @@ import (
|
|||||||
"github.com/miekg/dns"
|
"github.com/miekg/dns"
|
||||||
"go4.org/mem"
|
"go4.org/mem"
|
||||||
"golang.org/x/sync/errgroup"
|
"golang.org/x/sync/errgroup"
|
||||||
|
"tailscale.com/net/interfaces"
|
||||||
"tailscale.com/util/lineread"
|
"tailscale.com/util/lineread"
|
||||||
|
|
||||||
"github.com/Control-D-Inc/ctrld"
|
"github.com/Control-D-Inc/ctrld"
|
||||||
@@ -78,6 +80,7 @@ func (p *prog) serveDNS(listenerNum string) error {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
needRFC1918Listeners := listenerConfig.IP == "127.0.0.1" && listenerConfig.Port == 53
|
||||||
g, ctx := errgroup.WithContext(context.Background())
|
g, ctx := errgroup.WithContext(context.Background())
|
||||||
for _, proto := range []string{"udp", "tcp"} {
|
for _, proto := range []string{"udp", "tcp"} {
|
||||||
proto := proto
|
proto := proto
|
||||||
@@ -86,6 +89,7 @@ func (p *prog) serveDNS(listenerNum string) error {
|
|||||||
s, errCh := runDNSServer(net.JoinHostPort("::1", strconv.Itoa(listenerConfig.Port)), proto, handler)
|
s, errCh := runDNSServer(net.JoinHostPort("::1", strconv.Itoa(listenerConfig.Port)), proto, handler)
|
||||||
defer s.Shutdown()
|
defer s.Shutdown()
|
||||||
select {
|
select {
|
||||||
|
case <-p.stopCh:
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
case err := <-errCh:
|
case err := <-errCh:
|
||||||
// Local ipv6 listener should not terminate ctrld.
|
// Local ipv6 listener should not terminate ctrld.
|
||||||
@@ -95,17 +99,38 @@ func (p *prog) serveDNS(listenerNum string) error {
|
|||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
// When we spawn a listener on 127.0.0.1, also spawn listeners on the RFC1918
|
||||||
|
// addresses of the machine. So ctrld could receive queries from LAN clients.
|
||||||
|
if needRFC1918Listeners {
|
||||||
|
g.Go(func() error {
|
||||||
|
interfaces.ForeachInterface(func(i interfaces.Interface, prefixes []netip.Prefix) {
|
||||||
|
addrs, _ := i.Addrs()
|
||||||
|
for _, addr := range addrs {
|
||||||
|
ipNet, ok := addr.(*net.IPNet)
|
||||||
|
if !ok || !ipNet.IP.IsPrivate() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
func() {
|
||||||
|
listenAddr := net.JoinHostPort(ipNet.IP.String(), "53")
|
||||||
|
s, errCh := runDNSServer(listenAddr, proto, handler)
|
||||||
|
defer s.Shutdown()
|
||||||
|
select {
|
||||||
|
case <-p.stopCh:
|
||||||
|
case <-ctx.Done():
|
||||||
|
case err := <-errCh:
|
||||||
|
// RFC1918 listener should not terminate ctrld.
|
||||||
|
// It's a workaround for a quirk on system with systemd-resolved.
|
||||||
|
mainLog.Warn().Err(err).Msgf("could not listen on %s: %s", proto, listenAddr)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
g.Go(func() error {
|
g.Go(func() error {
|
||||||
s, errCh := runDNSServer(dnsListenAddress(listenerConfig), proto, handler)
|
s, errCh := runDNSServer(dnsListenAddress(listenerConfig), proto, handler)
|
||||||
defer s.Shutdown()
|
defer s.Shutdown()
|
||||||
if listenerConfig.Port == 0 {
|
|
||||||
switch s.Net {
|
|
||||||
case "udp":
|
|
||||||
mainLog.Info().Msgf("Random port chosen for udp listener.%s: %s", listenerNum, s.PacketConn.LocalAddr())
|
|
||||||
case "tcp":
|
|
||||||
mainLog.Info().Msgf("Random port chosen for tcp listener.%s: %s", listenerNum, s.Listener.Addr())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
select {
|
select {
|
||||||
case err := <-errCh:
|
case err := <-errCh:
|
||||||
return err
|
return err
|
||||||
@@ -113,11 +138,12 @@ func (p *prog) serveDNS(listenerNum string) error {
|
|||||||
p.started <- struct{}{}
|
p.started <- struct{}{}
|
||||||
}
|
}
|
||||||
select {
|
select {
|
||||||
|
case <-p.stopCh:
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
return nil
|
|
||||||
case err := <-errCh:
|
case err := <-errCh:
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return g.Wait()
|
return g.Wait()
|
||||||
|
|||||||
+1
-1
@@ -156,12 +156,12 @@ func (p *prog) run() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *prog) Stop(s service.Service) error {
|
func (p *prog) Stop(s service.Service) error {
|
||||||
|
mainLog.Info().Msg("Service stopped")
|
||||||
close(p.stopCh)
|
close(p.stopCh)
|
||||||
if err := p.deAllocateIP(); err != nil {
|
if err := p.deAllocateIP(); err != nil {
|
||||||
mainLog.Error().Err(err).Msg("de-allocate ip failed")
|
mainLog.Error().Err(err).Msg("de-allocate ip failed")
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
mainLog.Info().Msg("Service stopped")
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user