Skip to content

Commit

Permalink
Further refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
qdm12 committed May 18, 2024
1 parent bf46129 commit eda44d7
Show file tree
Hide file tree
Showing 13 changed files with 83 additions and 176 deletions.
16 changes: 8 additions & 8 deletions cmd/gluetun/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -382,22 +382,22 @@ func _main(ctx context.Context, buildInfo models.BuildInformation,
return fmt.Errorf("starting port forwarding loop: %w", err)
}

unboundLogger := logger.New(log.SetComponent("dns"))
unboundLooper, err := dns.NewLoop(allSettings.DNS, httpClient,
unboundLogger)
dnsLogger := logger.New(log.SetComponent("dns"))
dnsLooper, err := dns.NewLoop(allSettings.DNS, httpClient,
dnsLogger)
if err != nil {
return fmt.Errorf("creating DNS loop: %w", err)
}

dnsHandler, dnsCtx, dnsDone := goshutdown.NewGoRoutineHandler(
"dns", goroutine.OptionTimeout(defaultShutdownTimeout))
// wait for unboundLooper.Restart or its ticker launched with RunRestartTicker
go unboundLooper.Run(dnsCtx, dnsDone)
// wait for dnsLooper.Restart or its ticker launched with RunRestartTicker
go dnsLooper.Run(dnsCtx, dnsDone)
otherGroupHandler.Add(dnsHandler)

dnsTickerHandler, dnsTickerCtx, dnsTickerDone := goshutdown.NewGoRoutineHandler(
"dns ticker", goroutine.OptionTimeout(defaultShutdownTimeout))
go unboundLooper.RunRestartTicker(dnsTickerCtx, dnsTickerDone)
go dnsLooper.RunRestartTicker(dnsTickerCtx, dnsTickerDone)
controlGroupHandler.Add(dnsTickerHandler)

publicipAPI, _ := pubipapi.ParseProvider(allSettings.PublicIP.API)
Expand All @@ -424,7 +424,7 @@ func _main(ctx context.Context, buildInfo models.BuildInformation,
vpnLogger := logger.New(log.SetComponent("vpn"))
vpnLooper := vpn.NewLoop(allSettings.VPN, ipv6Supported, allSettings.Firewall.VPNInputPorts,
providers, storage, ovpnConf, netLinker, firewallConf, routingConf, portForwardLooper,
cmder, publicIPLooper, unboundLooper, vpnLogger, httpClient,
cmder, publicIPLooper, dnsLooper, vpnLogger, httpClient,
buildInfo, *allSettings.Version.Enabled)
vpnHandler, vpnCtx, vpnDone := goshutdown.NewGoRoutineHandler(
"vpn", goroutine.OptionTimeout(time.Second))
Expand Down Expand Up @@ -464,7 +464,7 @@ func _main(ctx context.Context, buildInfo models.BuildInformation,
"http server", goroutine.OptionTimeout(defaultShutdownTimeout))
httpServer, err := server.New(httpServerCtx, controlServerAddress, controlServerLogging,
logger.New(log.SetComponent("http server")),
buildInfo, vpnLooper, portForwardLooper, unboundLooper, updaterLooper, publicIPLooper,
buildInfo, vpnLooper, portForwardLooper, dnsLooper, updaterLooper, publicIPLooper,
storage, ipv6Supported)
if err != nil {
return fmt.Errorf("setting up control server: %w", err)
Expand Down
67 changes: 55 additions & 12 deletions internal/configuration/settings/dot.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ package settings
import (
"errors"
"fmt"
"net/netip"
"time"

"github.com/qdm12/dns/v2/pkg/provider"
"github.com/qdm12/gosettings"
"github.com/qdm12/gosettings/reader"
"github.com/qdm12/gotree"
Expand All @@ -16,14 +18,18 @@ type DoT struct {
// and used. It defaults to true, and cannot be nil
// in the internal state.
Enabled *bool
// UpdatePeriod is the period to update DNS block
// lists and cryptographic files for DNSSEC validation.
// UpdatePeriod is the period to update DNS block lists.
// It can be set to 0 to disable the update.
// It defaults to 24h and cannot be nil in
// the internal state.
UpdatePeriod *time.Duration
// Unbound contains settings to configure Unbound.
Unbound Unbound
// Providers is a list of DNS over TLS providers
Providers []string `json:"providers"`
// Caching is true if the DoT server should cache
// DNS responses.
Caching *bool `json:"caching"`
// IPv6 is true if the DoT server should connect over IPv6.
IPv6 *bool `json:"ipv6"`
// Blacklist contains settings to configure the filter
// block lists.
Blacklist DNSBlacklist
Expand All @@ -40,9 +46,12 @@ func (d DoT) validate() (err error) {
ErrDoTUpdatePeriodTooShort, *d.UpdatePeriod, minUpdatePeriod)
}

err = d.Unbound.validate()
if err != nil {
return err
providers := provider.NewProviders()
for _, providerName := range d.Providers {
_, err := providers.Get(providerName)
if err != nil {
return err
}
}

err = d.Blacklist.validate()
Expand All @@ -57,7 +66,9 @@ func (d *DoT) copy() (copied DoT) {
return DoT{
Enabled: gosettings.CopyPointer(d.Enabled),
UpdatePeriod: gosettings.CopyPointer(d.UpdatePeriod),
Unbound: d.Unbound.copy(),
Providers: gosettings.CopySlice(d.Providers),
Caching: gosettings.CopyPointer(d.Caching),
IPv6: gosettings.CopyPointer(d.IPv6),
Blacklist: d.Blacklist.copy(),
}
}
Expand All @@ -68,18 +79,36 @@ func (d *DoT) copy() (copied DoT) {
func (d *DoT) overrideWith(other DoT) {
d.Enabled = gosettings.OverrideWithPointer(d.Enabled, other.Enabled)
d.UpdatePeriod = gosettings.OverrideWithPointer(d.UpdatePeriod, other.UpdatePeriod)
d.Unbound.overrideWith(other.Unbound)
d.Providers = gosettings.OverrideWithSlice(d.Providers, other.Providers)
d.Caching = gosettings.OverrideWithPointer(d.Caching, other.Caching)
d.IPv6 = gosettings.OverrideWithPointer(d.IPv6, other.IPv6)
d.Blacklist.overrideWith(other.Blacklist)
}

func (d *DoT) setDefaults() {
d.Enabled = gosettings.DefaultPointer(d.Enabled, true)
const defaultUpdatePeriod = 24 * time.Hour
d.UpdatePeriod = gosettings.DefaultPointer(d.UpdatePeriod, defaultUpdatePeriod)
d.Unbound.setDefaults()
d.Providers = gosettings.DefaultSlice(d.Providers, []string{
provider.Cloudflare().Name,
})
d.Caching = gosettings.DefaultPointer(d.Caching, true)
d.IPv6 = gosettings.DefaultPointer(d.IPv6, false)
d.Blacklist.setDefaults()
}

func (d DoT) GetFirstPlaintextIPv4() (ipv4 netip.Addr) {
providers := provider.NewProviders()
provider, err := providers.Get(d.Providers[0])
if err != nil {
// Settings should be validated before calling this function,
// so an error happening here is a programming error.
panic(err)
}

return provider.DoT.IPv4[0].Addr()
}

func (d DoT) String() string {
return d.toLinesNode().String()
}
Expand All @@ -98,7 +127,14 @@ func (d DoT) toLinesNode() (node *gotree.Node) {
}
node.Appendf("Update period: %s", update)

node.AppendNode(d.Unbound.toLinesNode())
authServers := node.Appendf("Authoritative servers:")
for _, provider := range d.Providers {
authServers.Appendf(provider)
}

node.Appendf("Caching: %s", gosettings.BoolToYesNo(d.Caching))
node.Appendf("IPv6: %s", gosettings.BoolToYesNo(d.IPv6))

node.AppendNode(d.Blacklist.toLinesNode())

return node
Expand All @@ -115,7 +151,14 @@ func (d *DoT) read(reader *reader.Reader) (err error) {
return err
}

err = d.Unbound.read(reader)
d.Providers = reader.CSV("DOT_PROVIDERS")

d.Caching, err = reader.BoolPtr("DOT_CACHING")
if err != nil {
return err
}

d.IPv6, err = reader.BoolPtr("DOT_IPV6")
if err != nil {
return err
}
Expand Down
9 changes: 4 additions & 5 deletions internal/configuration/settings/settings_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,10 @@ func Test_Settings_String(t *testing.T) {
| └── DNS over TLS settings:
| ├── Enabled: yes
| ├── Update period: every 24h0m0s
| ├── DNS over TLS settings:
| | ├── Authoritative servers:
| | | └── Cloudflare
| | ├── Caching: yes
| | └── IPv6: no
| ├── Authoritative servers:
| | └── Cloudflare
| ├── Caching: yes
| ├── IPv6: no
| └── DNS filtering settings:
| ├── Block malicious: yes
| ├── Block ads: no
Expand Down
102 changes: 0 additions & 102 deletions internal/configuration/settings/unbound.go

This file was deleted.

32 changes: 0 additions & 32 deletions internal/configuration/settings/unbound_test.go

This file was deleted.

2 changes: 1 addition & 1 deletion internal/dns/plaintext.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ func (l *Loop) useUnencryptedDNS(fallback bool) {
if settings.ServerAddress.Compare(netip.AddrFrom4([4]byte{127, 0, 0, 1})) != 0 {
targetIP = settings.ServerAddress
} else {
targetIP = settings.DoT.Unbound.GetFirstPlaintextIPv4()
targetIP = settings.DoT.GetFirstPlaintextIPv4()
}

if fallback {
Expand Down
4 changes: 2 additions & 2 deletions internal/dns/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,14 @@ func (l *Loop) Run(ctx context.Context, done chan<- struct{}) {
}

for ctx.Err() == nil {
// Upper scope variables for Unbound only
// Upper scope variables for the DNS over TLS server only
// Their values are to be used if DOT=off
var runError <-chan error

settings := l.GetSettings()
for !*settings.KeepNameserver && *settings.DoT.Enabled {
var err error
runError, err = l.setupUnbound(ctx)
runError, err = l.setupServer(ctx)
if err == nil {
l.backoffTime = defaultBackoffTime
l.logger.Info("ready")
Expand Down
10 changes: 5 additions & 5 deletions internal/dns/settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func buildDoTSettings(settings settings.DNS,
dotSettings dot.ServerSettings, err error) {
var middlewares []dot.Middleware

if *settings.DoT.Unbound.Caching {
if *settings.DoT.Caching {
lruCache, err := lru.New(lru.Settings{})
if err != nil {
return dot.ServerSettings{}, fmt.Errorf("creating LRU cache: %w", err)
Expand All @@ -48,17 +48,17 @@ func buildDoTSettings(settings settings.DNS,
middlewares = append(middlewares, filterMiddleware)

providersData := provider.NewProviders()
providers := make([]provider.Provider, len(settings.DoT.Unbound.Providers))
for i := range settings.DoT.Unbound.Providers {
providers := make([]provider.Provider, len(settings.DoT.Providers))
for i := range settings.DoT.Providers {
var err error
providers[i], err = providersData.Get(settings.DoT.Unbound.Providers[i])
providers[i], err = providersData.Get(settings.DoT.Providers[i])
if err != nil {
panic(err) // this should already had been checked
}
}

ipVersion := "ipv4"
if *settings.DoT.Unbound.IPv6 {
if *settings.DoT.IPv6 {
ipVersion = "ipv6"
}
return dot.ServerSettings{
Expand Down
Loading

0 comments on commit eda44d7

Please sign in to comment.