cmd/ctrld: add TCP listener

Fixes #25
This commit is contained in:
Cuong Manh Le
2023-03-14 09:43:40 +07:00
committed by Cuong Manh Le
parent 7dab688252
commit 3e6f6cc721
2 changed files with 30 additions and 18 deletions
+28 -16
View File
@@ -12,6 +12,7 @@ import (
"time" "time"
"github.com/miekg/dns" "github.com/miekg/dns"
"golang.org/x/sync/errgroup"
"github.com/Control-D-Inc/ctrld" "github.com/Control-D-Inc/ctrld"
"github.com/Control-D-Inc/ctrld/internal/dnscache" "github.com/Control-D-Inc/ctrld/internal/dnscache"
@@ -20,7 +21,7 @@ import (
const staleTTL = 60 * time.Second const staleTTL = 60 * time.Second
func (p *prog) serveUDP(listenerNum string) error { func (p *prog) serveDNS(listenerNum string) error {
listenerConfig := p.cfg.Listener[listenerNum] listenerConfig := p.cfg.Listener[listenerNum]
// make sure ip is allocated // make sure ip is allocated
if allocErr := p.allocateIP(listenerConfig.IP); allocErr != nil { if allocErr := p.allocateIP(listenerConfig.IP); allocErr != nil {
@@ -55,27 +56,38 @@ func (p *prog) serveUDP(listenerNum string) error {
} }
}) })
// On Windows, there's no easy way for disabling/removing IPv6 DNS resolver, so we check whether we can g := new(errgroup.Group)
// listen on ::1, then spawn a listener for receiving DNS requests. for _, proto := range []string{"udp", "tcp"} {
if runtime.GOOS == "windows" && ctrldnet.SupportsIPv6ListenLocal() { proto := proto
go func() { // On Windows, there's no easy way for disabling/removing IPv6 DNS resolver, so we check whether we can
// listen on ::1, then spawn a listener for receiving DNS requests.
if runtime.GOOS == "windows" && ctrldnet.SupportsIPv6ListenLocal() {
g.Go(func() error {
s := &dns.Server{
Addr: net.JoinHostPort("::1", strconv.Itoa(listenerConfig.Port)),
Net: proto,
Handler: handler,
}
if err := s.ListenAndServe(); err != nil {
mainLog.Error().Err(err).Msg("could not serving on ::1")
}
return nil
})
}
g.Go(func() error {
s := &dns.Server{ s := &dns.Server{
Addr: net.JoinHostPort("::1", strconv.Itoa(listenerConfig.Port)), Addr: net.JoinHostPort(listenerConfig.IP, strconv.Itoa(listenerConfig.Port)),
Net: "udp", Net: proto,
Handler: handler, Handler: handler,
} }
if err := s.ListenAndServe(); err != nil { if err := s.ListenAndServe(); err != nil {
mainLog.Error().Err(err).Msg("could not serving on ::1") mainLog.Error().Err(err).Msgf("could not listen and serve on: %s", s.Addr)
return err
} }
}() return nil
})
} }
return g.Wait()
s := &dns.Server{
Addr: net.JoinHostPort(listenerConfig.IP, strconv.Itoa(listenerConfig.Port)),
Net: "udp",
Handler: handler,
}
return s.ListenAndServe()
} }
func (p *prog) upstreamFor(ctx context.Context, defaultUpstreamNum string, lc *ctrld.ListenerConfig, addr net.Addr, domain string) ([]string, bool) { func (p *prog) upstreamFor(ctx context.Context, defaultUpstreamNum string, lc *ctrld.ListenerConfig, addr net.Addr, domain string) ([]string, bool) {
+2 -2
View File
@@ -85,7 +85,7 @@ func (p *prog) run() {
} }
addr := net.JoinHostPort(listenerConfig.IP, strconv.Itoa(listenerConfig.Port)) addr := net.JoinHostPort(listenerConfig.IP, strconv.Itoa(listenerConfig.Port))
mainLog.Info().Msgf("Starting DNS server on listener.%s: %s", listenerNum, addr) mainLog.Info().Msgf("Starting DNS server on listener.%s: %s", listenerNum, addr)
err := p.serveUDP(listenerNum) err := p.serveDNS(listenerNum)
if err != nil && !defaultConfigWritten && cdUID == "" { if err != nil && !defaultConfigWritten && cdUID == "" {
mainLog.Fatal().Err(err).Msgf("Unable to start dns proxy on listener.%s", listenerNum) mainLog.Fatal().Err(err).Msgf("Unable to start dns proxy on listener.%s", listenerNum)
return return
@@ -109,7 +109,7 @@ func (p *prog) run() {
p.cfg.Service.AllocateIP = true p.cfg.Service.AllocateIP = true
p.preRun() p.preRun()
mainLog.Info().Msgf("Starting DNS server on listener.%s: %s", listenerNum, net.JoinHostPort(ip, strconv.Itoa(port))) mainLog.Info().Msgf("Starting DNS server on listener.%s: %s", listenerNum, net.JoinHostPort(ip, strconv.Itoa(port)))
if err := p.serveUDP(listenerNum); err != nil { if err := p.serveDNS(listenerNum); err != nil {
mainLog.Fatal().Err(err).Msgf("Unable to start dns proxy on listener.%s", listenerNum) mainLog.Fatal().Err(err).Msgf("Unable to start dns proxy on listener.%s", listenerNum)
return return
} }