88 lines
2.5 KiB
Go
88 lines
2.5 KiB
Go
package main
|
|
|
|
import (
|
|
"github.com/rs/zerolog"
|
|
|
|
"github.com/cloudflare/cloudflared/config"
|
|
"github.com/cloudflare/cloudflared/tunneldns"
|
|
)
|
|
|
|
const (
|
|
// ResolverServiceType is used to identify what kind of overwatch service this is
|
|
ResolverServiceType = "resolver"
|
|
|
|
LogFieldResolverAddress = "resolverAddress"
|
|
LogFieldResolverPort = "resolverPort"
|
|
LogFieldResolverMaxUpstreamConns = "resolverMaxUpstreamConns"
|
|
)
|
|
|
|
// ResolverService is used to wrap the tunneldns package's DNS over HTTP
|
|
// into a service model for the overwatch package.
|
|
// it also holds a reference to the config object that represents its state
|
|
type ResolverService struct {
|
|
resolver config.DNSResolver
|
|
shutdown chan struct{}
|
|
log *zerolog.Logger
|
|
}
|
|
|
|
// NewResolverService creates a new resolver service
|
|
func NewResolverService(r config.DNSResolver, log *zerolog.Logger) *ResolverService {
|
|
return &ResolverService{resolver: r,
|
|
shutdown: make(chan struct{}),
|
|
log: log,
|
|
}
|
|
}
|
|
|
|
// Name is used to figure out this service is related to the others (normally the addr it binds to)
|
|
// this is just "resolver" since there can only be one DNS resolver running
|
|
func (s *ResolverService) Name() string {
|
|
return ResolverServiceType
|
|
}
|
|
|
|
// Type is used to identify what kind of overwatch service this is
|
|
func (s *ResolverService) Type() string {
|
|
return ResolverServiceType
|
|
}
|
|
|
|
// Hash is used to figure out if this forwarder is the unchanged or not from the config file updates
|
|
func (s *ResolverService) Hash() string {
|
|
return s.resolver.Hash()
|
|
}
|
|
|
|
// Shutdown stops the tunneldns listener
|
|
func (s *ResolverService) Shutdown() {
|
|
s.shutdown <- struct{}{}
|
|
}
|
|
|
|
// Run is the run loop that is started by the overwatch service
|
|
func (s *ResolverService) Run() error {
|
|
// create a listener
|
|
l, err := tunneldns.CreateListener(s.resolver.AddressOrDefault(), s.resolver.PortOrDefault(),
|
|
s.resolver.UpstreamsOrDefault(), s.resolver.BootstrapsOrDefault(), s.resolver.MaxUpstreamConnectionsOrDefault(), s.log)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// start the listener.
|
|
readySignal := make(chan struct{})
|
|
err = l.Start(readySignal)
|
|
if err != nil {
|
|
_ = l.Stop()
|
|
return err
|
|
}
|
|
<-readySignal
|
|
|
|
resolverLog := s.log.With().
|
|
Str(LogFieldResolverAddress, s.resolver.AddressOrDefault()).
|
|
Uint16(LogFieldResolverPort, s.resolver.PortOrDefault()).
|
|
Int(LogFieldResolverMaxUpstreamConns, s.resolver.MaxUpstreamConnectionsOrDefault()).
|
|
Logger()
|
|
|
|
resolverLog.Info().Msg("Starting resolver")
|
|
|
|
// wait for shutdown signal
|
|
<-s.shutdown
|
|
resolverLog.Info().Msg("Shutting down resolver")
|
|
return l.Stop()
|
|
}
|