Restructure modules (#1572)
* Move portbase into monorepo * Add new simple module mgr * [WIP] Switch to new simple module mgr * Add StateMgr and more worker variants * [WIP] Switch more modules * [WIP] Switch more modules * [WIP] swtich more modules * [WIP] switch all SPN modules * [WIP] switch all service modules * [WIP] Convert all workers to the new module system * [WIP] add new task system to module manager * [WIP] Add second take for scheduling workers * [WIP] Add FIXME for bugs in new scheduler * [WIP] Add minor improvements to scheduler * [WIP] Add new worker scheduler * [WIP] Fix more bug related to new module system * [WIP] Fix start handing of the new module system * [WIP] Improve startup process * [WIP] Fix minor issues * [WIP] Fix missing subsystem in settings * [WIP] Initialize managers in constructor * [WIP] Move module event initialization to constrictors * [WIP] Fix setting for enabling and disabling the SPN module * [WIP] Move API registeration into module construction * [WIP] Update states mgr for all modules * [WIP] Add CmdLine operation support * Add state helper methods to module group and instance * Add notification and module status handling to status package * Fix starting issues * Remove pilot widget and update security lock to new status data * Remove debug logs * Improve http server shutdown * Add workaround for cleanly shutting down firewall+netquery * Improve logging * Add syncing states with notifications for new module system * Improve starting, stopping, shutdown; resolve FIXMEs/TODOs * [WIP] Fix most unit tests * Review new module system and fix minor issues * Push shutdown and restart events again via API * Set sleep mode via interface * Update example/template module * [WIP] Fix spn/cabin unit test * Remove deprecated UI elements * Make log output more similar for the logging transition phase * Switch spn hub and observer cmds to new module system * Fix log sources * Make worker mgr less error prone * Fix tests and minor issues * Fix observation hub * Improve shutdown and restart handling * Split up big connection.go source file * Move varint and dsd packages to structures repo * Improve expansion test * Fix linter warnings * Fix interception module on windows * Fix linter errors --------- Co-authored-by: Vladimir Stoilov <vladimir@safing.io>
This commit is contained in:
@@ -3,15 +3,14 @@ package resolver
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/safing/portbase/api"
|
||||
"github.com/safing/portbase/database/record"
|
||||
"github.com/safing/portmaster/base/api"
|
||||
"github.com/safing/portmaster/base/database/record"
|
||||
)
|
||||
|
||||
func registerAPI() error {
|
||||
if err := api.RegisterEndpoint(api.Endpoint{
|
||||
Path: "dns/clear",
|
||||
Write: api.PermitUser,
|
||||
BelongsTo: module,
|
||||
ActionFunc: clearNameCacheHandler,
|
||||
Name: "Clear cached DNS records",
|
||||
Description: "Deletes all saved DNS records from the database.",
|
||||
@@ -22,7 +21,6 @@ func registerAPI() error {
|
||||
if err := api.RegisterEndpoint(api.Endpoint{
|
||||
Path: "dns/resolvers",
|
||||
Read: api.PermitAnyone,
|
||||
BelongsTo: module,
|
||||
StructFunc: exportDNSResolvers,
|
||||
Name: "List DNS Resolvers",
|
||||
Description: "List currently configured DNS resolvers and their status.",
|
||||
@@ -31,9 +29,8 @@ func registerAPI() error {
|
||||
}
|
||||
|
||||
if err := api.RegisterEndpoint(api.Endpoint{
|
||||
Path: `dns/cache/{query:[a-z0-9\.-]{0,512}\.[A-Z]{1,32}}`,
|
||||
Read: api.PermitUser,
|
||||
BelongsTo: module,
|
||||
Path: `dns/cache/{query:[a-z0-9\.-]{0,512}\.[A-Z]{1,32}}`,
|
||||
Read: api.PermitUser,
|
||||
RecordFunc: func(r *api.Request) (record.Record, error) {
|
||||
return recordDatabase.Get(nameRecordsKeyPrefix + r.URLVars["query"])
|
||||
},
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/safing/portbase/config"
|
||||
"github.com/safing/portmaster/base/config"
|
||||
"github.com/safing/portmaster/service/netenv"
|
||||
"github.com/safing/portmaster/service/status"
|
||||
)
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
package resolver
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/safing/portbase/log"
|
||||
"github.com/safing/portbase/modules"
|
||||
"github.com/safing/portmaster/base/log"
|
||||
"github.com/safing/portmaster/service/mgr"
|
||||
"github.com/safing/portmaster/service/netenv"
|
||||
)
|
||||
|
||||
@@ -71,9 +70,12 @@ func (brc *BasicResolverConn) ResetFailure() {
|
||||
}
|
||||
}
|
||||
|
||||
func checkFailingResolvers(ctx context.Context, task *modules.Task) error {
|
||||
func checkFailingResolvers(wc *mgr.WorkerCtx) error {
|
||||
var resolvers []*Resolver
|
||||
|
||||
// Set next execution time.
|
||||
module.failingResolverWorkerMgr.Delay(time.Duration(nameserverRetryRate()) * time.Second)
|
||||
|
||||
// Make a copy of the resolver list.
|
||||
func() {
|
||||
resolversLock.Lock()
|
||||
@@ -84,7 +86,7 @@ func checkFailingResolvers(ctx context.Context, task *modules.Task) error {
|
||||
}()
|
||||
|
||||
// Start logging.
|
||||
ctx, tracer := log.AddTracer(ctx)
|
||||
ctx, tracer := log.AddTracer(wc.Ctx())
|
||||
tracer.Debugf("resolver: checking failed resolvers")
|
||||
defer tracer.Submit()
|
||||
|
||||
@@ -116,10 +118,5 @@ func checkFailingResolvers(ctx context.Context, task *modules.Task) error {
|
||||
}
|
||||
}
|
||||
|
||||
// Set next execution time.
|
||||
if task != nil {
|
||||
task.Schedule(time.Now().Add(time.Duration(nameserverRetryRate()) * time.Second))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -6,8 +6,8 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/safing/portbase/database"
|
||||
"github.com/safing/portbase/database/record"
|
||||
"github.com/safing/portmaster/base/database"
|
||||
"github.com/safing/portmaster/base/database/record"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@@ -2,27 +2,54 @@ package resolver
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/tevino/abool"
|
||||
|
||||
"github.com/safing/portbase/log"
|
||||
"github.com/safing/portbase/modules"
|
||||
"github.com/safing/portbase/notifications"
|
||||
"github.com/safing/portbase/utils/debug"
|
||||
"github.com/safing/portmaster/base/config"
|
||||
"github.com/safing/portmaster/base/log"
|
||||
"github.com/safing/portmaster/base/notifications"
|
||||
"github.com/safing/portmaster/base/utils/debug"
|
||||
_ "github.com/safing/portmaster/service/core/base"
|
||||
"github.com/safing/portmaster/service/intel"
|
||||
"github.com/safing/portmaster/service/mgr"
|
||||
"github.com/safing/portmaster/service/netenv"
|
||||
)
|
||||
|
||||
var module *modules.Module
|
||||
// ResolverModule is the DNS resolver module.
|
||||
type ResolverModule struct { //nolint
|
||||
mgr *mgr.Manager
|
||||
instance instance
|
||||
|
||||
func init() {
|
||||
module = modules.Register("resolver", prep, start, nil, "base", "netenv")
|
||||
failingResolverWorkerMgr *mgr.WorkerMgr
|
||||
suggestUsingStaleCacheTask *mgr.WorkerMgr
|
||||
|
||||
states *mgr.StateMgr
|
||||
}
|
||||
|
||||
// Manager returns the module manager.
|
||||
func (rm *ResolverModule) Manager() *mgr.Manager {
|
||||
return rm.mgr
|
||||
}
|
||||
|
||||
// States returns the module state manager.
|
||||
func (rm *ResolverModule) States() *mgr.StateMgr {
|
||||
return rm.states
|
||||
}
|
||||
|
||||
// Start starts the module.
|
||||
func (rm *ResolverModule) Start() error {
|
||||
return start()
|
||||
}
|
||||
|
||||
// Stop stops the module.
|
||||
func (rm *ResolverModule) Stop() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func prep() error {
|
||||
@@ -49,41 +76,28 @@ func start() error {
|
||||
loadResolvers()
|
||||
|
||||
// reload after network change
|
||||
err := module.RegisterEventHook(
|
||||
"netenv",
|
||||
"network changed",
|
||||
module.instance.NetEnv().EventNetworkChange.AddCallback(
|
||||
"update nameservers",
|
||||
func(_ context.Context, _ interface{}) error {
|
||||
func(_ *mgr.WorkerCtx, _ struct{}) (bool, error) {
|
||||
loadResolvers()
|
||||
log.Debug("resolver: reloaded nameservers due to network change")
|
||||
return nil
|
||||
return false, nil
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Force resolvers to reconnect when SPN has connected.
|
||||
if err := module.RegisterEventHook(
|
||||
"captain",
|
||||
"spn connect", // Defined by captain.SPNConnectedEvent
|
||||
module.instance.GetEventSPNConnected().AddCallback(
|
||||
"force resolver reconnect",
|
||||
func(ctx context.Context, _ any) error {
|
||||
ForceResolverReconnect(ctx)
|
||||
return nil
|
||||
},
|
||||
); err != nil {
|
||||
// This module does not depend on the SPN/Captain module, and probably should not.
|
||||
log.Warningf("resolvers: failed to register event hook for captain/spn-connect: %s", err)
|
||||
}
|
||||
func(ctx *mgr.WorkerCtx, _ struct{}) (bool, error) {
|
||||
ForceResolverReconnect(ctx.Ctx())
|
||||
return false, nil
|
||||
})
|
||||
|
||||
// reload after config change
|
||||
prevNameservers := strings.Join(configuredNameServers(), " ")
|
||||
err = module.RegisterEventHook(
|
||||
"config",
|
||||
"config change",
|
||||
module.instance.Config().EventConfigChange.AddCallback(
|
||||
"update nameservers",
|
||||
func(_ context.Context, _ interface{}) error {
|
||||
func(_ *mgr.WorkerCtx, _ struct{}) (bool, error) {
|
||||
newNameservers := strings.Join(configuredNameServers(), " ")
|
||||
if newNameservers != prevNameservers {
|
||||
prevNameservers = newNameservers
|
||||
@@ -91,38 +105,28 @@ func start() error {
|
||||
loadResolvers()
|
||||
log.Debug("resolver: reloaded nameservers due to config change")
|
||||
}
|
||||
return nil
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return false, nil
|
||||
})
|
||||
|
||||
// Check failing resolvers regularly and when the network changes.
|
||||
checkFailingResolversTask := module.NewTask("check failing resolvers", checkFailingResolvers).Repeat(1 * time.Minute)
|
||||
err = module.RegisterEventHook(
|
||||
"netenv",
|
||||
netenv.NetworkChangedEvent,
|
||||
module.failingResolverWorkerMgr = module.mgr.NewWorkerMgr("check failing resolvers", checkFailingResolvers, nil)
|
||||
module.failingResolverWorkerMgr.Go()
|
||||
module.instance.NetEnv().EventNetworkChange.AddCallback(
|
||||
"check failing resolvers",
|
||||
func(_ context.Context, _ any) error {
|
||||
checkFailingResolversTask.StartASAP()
|
||||
return nil
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
func(wc *mgr.WorkerCtx, _ struct{}) (bool, error) {
|
||||
return false, checkFailingResolvers(wc)
|
||||
})
|
||||
|
||||
module.NewTask("suggest using stale cache", suggestUsingStaleCacheTask).Repeat(2 * time.Minute)
|
||||
module.suggestUsingStaleCacheTask = module.mgr.NewWorkerMgr("suggest using stale cache", suggestUsingStaleCacheTask, nil)
|
||||
module.suggestUsingStaleCacheTask.Go()
|
||||
|
||||
module.StartServiceWorker(
|
||||
module.mgr.Go(
|
||||
"mdns handler",
|
||||
5*time.Second,
|
||||
listenToMDNS,
|
||||
)
|
||||
|
||||
module.StartServiceWorker("name record delayed cache writer", 0, recordDatabase.DelayedCacheWriter)
|
||||
module.StartServiceWorker("ip info delayed cache writer", 0, ipInfoDatabase.DelayedCacheWriter)
|
||||
module.mgr.Go("name record delayed cache writer", recordDatabase.DelayedCacheWriter)
|
||||
module.mgr.Go("ip info delayed cache writer", ipInfoDatabase.DelayedCacheWriter)
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -188,7 +192,7 @@ This notification will go away when Portmaster detects a working configured DNS
|
||||
notifications.Notify(n)
|
||||
|
||||
failingResolverNotification = n
|
||||
n.AttachToModule(module)
|
||||
n.SyncWithState(module.states)
|
||||
}
|
||||
|
||||
func resetFailingResolversNotification() {
|
||||
@@ -206,7 +210,7 @@ func resetFailingResolversNotification() {
|
||||
}
|
||||
|
||||
// Additionally, resolve the module error, if not done through the notification.
|
||||
module.Resolve(failingResolverErrorID)
|
||||
module.states.Remove(failingResolverErrorID)
|
||||
}
|
||||
|
||||
// AddToDebugInfo adds the system status to the given debug.Info.
|
||||
@@ -250,3 +254,32 @@ func AddToDebugInfo(di *debug.Info) {
|
||||
content...,
|
||||
)
|
||||
}
|
||||
|
||||
var (
|
||||
module *ResolverModule
|
||||
shimLoaded atomic.Bool
|
||||
)
|
||||
|
||||
// New returns a new Resolver module.
|
||||
func New(instance instance) (*ResolverModule, error) {
|
||||
if !shimLoaded.CompareAndSwap(false, true) {
|
||||
return nil, errors.New("only one instance allowed")
|
||||
}
|
||||
m := mgr.New("Resolver")
|
||||
module = &ResolverModule{
|
||||
mgr: m,
|
||||
instance: instance,
|
||||
|
||||
states: mgr.NewStateMgr(m),
|
||||
}
|
||||
if err := prep(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return module, nil
|
||||
}
|
||||
|
||||
type instance interface {
|
||||
NetEnv() *netenv.NetEnv
|
||||
Config() *config.Config
|
||||
GetEventSPNConnected() *mgr.EventMgr[struct{}]
|
||||
}
|
||||
|
||||
@@ -1,15 +1,143 @@
|
||||
package resolver
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/safing/portmaster/service/core/pmtesting"
|
||||
"github.com/safing/portmaster/base/api"
|
||||
"github.com/safing/portmaster/base/config"
|
||||
"github.com/safing/portmaster/base/database/dbmodule"
|
||||
"github.com/safing/portmaster/base/notifications"
|
||||
"github.com/safing/portmaster/service/core/base"
|
||||
"github.com/safing/portmaster/service/mgr"
|
||||
"github.com/safing/portmaster/service/netenv"
|
||||
"github.com/safing/portmaster/service/updates"
|
||||
)
|
||||
|
||||
var domainFeed = make(chan string)
|
||||
|
||||
type testInstance struct {
|
||||
db *dbmodule.DBModule
|
||||
base *base.Base
|
||||
api *api.API
|
||||
config *config.Config
|
||||
updates *updates.Updates
|
||||
netenv *netenv.NetEnv
|
||||
}
|
||||
|
||||
// var _ instance = &testInstance{}
|
||||
|
||||
func (stub *testInstance) Updates() *updates.Updates {
|
||||
return stub.updates
|
||||
}
|
||||
|
||||
func (stub *testInstance) API() *api.API {
|
||||
return stub.api
|
||||
}
|
||||
|
||||
func (stub *testInstance) Config() *config.Config {
|
||||
return stub.config
|
||||
}
|
||||
|
||||
func (stub *testInstance) NetEnv() *netenv.NetEnv {
|
||||
return stub.netenv
|
||||
}
|
||||
|
||||
func (stub *testInstance) Notifications() *notifications.Notifications {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (stub *testInstance) Ready() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (stub *testInstance) Restart() {}
|
||||
|
||||
func (stub *testInstance) Shutdown() {}
|
||||
|
||||
func (stub *testInstance) SetCmdLineOperation(f func() error) {}
|
||||
|
||||
func (stub *testInstance) GetEventSPNConnected() *mgr.EventMgr[struct{}] {
|
||||
return mgr.NewEventMgr[struct{}]("spn connect", nil)
|
||||
}
|
||||
|
||||
func runTest(m *testing.M) error {
|
||||
api.SetDefaultAPIListenAddress("0.0.0.0:8080")
|
||||
ds, err := config.InitializeUnitTestDataroot("test-resolver")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to initialize dataroot: %w", err)
|
||||
}
|
||||
defer func() { _ = os.RemoveAll(ds) }()
|
||||
|
||||
stub := &testInstance{}
|
||||
stub.db, err = dbmodule.New(stub)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create database: %w", err)
|
||||
}
|
||||
stub.config, err = config.New(stub)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create config: %w", err)
|
||||
}
|
||||
stub.base, err = base.New(stub)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create base: %w", err)
|
||||
}
|
||||
stub.api, err = api.New(stub)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create api: %w", err)
|
||||
}
|
||||
stub.netenv, err = netenv.New(stub)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create netenv: %w", err)
|
||||
}
|
||||
stub.updates, err = updates.New(stub)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create updates: %w", err)
|
||||
}
|
||||
module, err := New(stub)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create module: %w", err)
|
||||
}
|
||||
|
||||
err = stub.db.Start()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to start database: %w", err)
|
||||
}
|
||||
err = stub.config.Start()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to start config: %w", err)
|
||||
}
|
||||
err = stub.base.Start()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to start base: %w", err)
|
||||
}
|
||||
err = stub.api.Start()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to start api: %w", err)
|
||||
}
|
||||
err = stub.updates.Start()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to start updates: %w", err)
|
||||
}
|
||||
err = stub.netenv.Start()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to start netenv: %w", err)
|
||||
}
|
||||
err = module.Start()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to start module: %w", err)
|
||||
}
|
||||
|
||||
m.Run()
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
pmtesting.TestMain(m, module)
|
||||
if err := runTest(m); err != nil {
|
||||
fmt.Printf("%s", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
package resolver
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/safing/portbase/log"
|
||||
"github.com/safing/portbase/modules"
|
||||
"github.com/safing/portbase/notifications"
|
||||
"github.com/safing/portmaster/base/log"
|
||||
"github.com/safing/portmaster/base/notifications"
|
||||
"github.com/safing/portmaster/service/mgr"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -49,11 +48,12 @@ func resetSlowQueriesSensorValue() {
|
||||
|
||||
var suggestUsingStaleCacheNotification *notifications.Notification
|
||||
|
||||
func suggestUsingStaleCacheTask(ctx context.Context, t *modules.Task) error {
|
||||
func suggestUsingStaleCacheTask(_ *mgr.WorkerCtx) error {
|
||||
scheduleNextCall := true
|
||||
switch {
|
||||
case useStaleCache() || useStaleCacheConfigOption.IsSetByUser():
|
||||
// If setting is already active, disable task repeating.
|
||||
t.Repeat(0)
|
||||
scheduleNextCall = false
|
||||
|
||||
// Delete local reference, if used.
|
||||
if suggestUsingStaleCacheNotification != nil {
|
||||
@@ -102,6 +102,9 @@ func suggestUsingStaleCacheTask(ctx context.Context, t *modules.Task) error {
|
||||
notifications.Notify(suggestUsingStaleCacheNotification)
|
||||
}
|
||||
|
||||
if scheduleNextCall {
|
||||
_ = module.suggestUsingStaleCacheTask.Delay(2 * time.Minute)
|
||||
}
|
||||
resetSlowQueriesSensorValue()
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -6,11 +6,11 @@ import (
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/safing/portbase/api"
|
||||
"github.com/safing/portbase/database"
|
||||
"github.com/safing/portbase/database/query"
|
||||
"github.com/safing/portbase/database/record"
|
||||
"github.com/safing/portbase/log"
|
||||
"github.com/safing/portmaster/base/api"
|
||||
"github.com/safing/portmaster/base/database"
|
||||
"github.com/safing/portmaster/base/database/query"
|
||||
"github.com/safing/portmaster/base/database/record"
|
||||
"github.com/safing/portmaster/base/log"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@@ -12,8 +12,9 @@ import (
|
||||
"github.com/miekg/dns"
|
||||
"golang.org/x/net/publicsuffix"
|
||||
|
||||
"github.com/safing/portbase/database"
|
||||
"github.com/safing/portbase/log"
|
||||
"github.com/safing/portmaster/base/database"
|
||||
"github.com/safing/portmaster/base/log"
|
||||
"github.com/safing/portmaster/service/mgr"
|
||||
"github.com/safing/portmaster/service/netenv"
|
||||
)
|
||||
|
||||
@@ -307,8 +308,8 @@ func startAsyncQuery(ctx context.Context, q *Query, currentRRCache *RRCache) {
|
||||
}
|
||||
|
||||
// resolve async
|
||||
module.StartWorker("resolve async", func(asyncCtx context.Context) error {
|
||||
tracingCtx, tracer := log.AddTracer(asyncCtx)
|
||||
module.mgr.Go("resolve async", func(wc *mgr.WorkerCtx) error {
|
||||
tracingCtx, tracer := log.AddTracer(wc.Ctx())
|
||||
defer tracer.Submit()
|
||||
tracer.Tracef("resolver: resolving %s async", q.ID())
|
||||
_, err := resolveAndCache(tracingCtx, q, nil)
|
||||
@@ -412,7 +413,7 @@ func resolveAndCache(ctx context.Context, q *Query, oldCache *RRCache) (rrCache
|
||||
|
||||
// start resolving
|
||||
for _, resolver := range resolvers {
|
||||
if module.IsStopping() {
|
||||
if module.mgr.IsDone() {
|
||||
return nil, ErrShuttingDown
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
|
||||
"github.com/miekg/dns"
|
||||
|
||||
"github.com/safing/portbase/log"
|
||||
"github.com/safing/portmaster/base/log"
|
||||
"github.com/safing/portmaster/service/netenv"
|
||||
"github.com/safing/portmaster/service/network/netutils"
|
||||
)
|
||||
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
|
||||
"github.com/miekg/dns"
|
||||
|
||||
"github.com/safing/portbase/log"
|
||||
"github.com/safing/portmaster/base/log"
|
||||
"github.com/safing/portmaster/service/netenv"
|
||||
)
|
||||
|
||||
|
||||
@@ -11,7 +11,8 @@ import (
|
||||
|
||||
"github.com/miekg/dns"
|
||||
|
||||
"github.com/safing/portbase/log"
|
||||
"github.com/safing/portmaster/base/log"
|
||||
"github.com/safing/portmaster/service/mgr"
|
||||
"github.com/safing/portmaster/service/netenv"
|
||||
"github.com/safing/portmaster/service/network/netutils"
|
||||
)
|
||||
@@ -74,7 +75,7 @@ func indexOfRR(entry *dns.RR_Header, list *[]dns.RR) int {
|
||||
}
|
||||
|
||||
//nolint:gocyclo,gocognit // TODO: make simpler
|
||||
func listenToMDNS(ctx context.Context) error {
|
||||
func listenToMDNS(wc *mgr.WorkerCtx) error {
|
||||
var err error
|
||||
messages := make(chan *dns.Msg, 32)
|
||||
|
||||
@@ -86,8 +87,8 @@ func listenToMDNS(ctx context.Context) error {
|
||||
// TODO: retry after some time
|
||||
log.Warningf("intel(mdns): failed to create udp4 listen multicast socket: %s", err)
|
||||
} else {
|
||||
module.StartServiceWorker("mdns udp4 multicast listener", 0, func(ctx context.Context) error {
|
||||
return listenForDNSPackets(ctx, multicast4Conn, messages)
|
||||
module.mgr.Go("mdns udp4 multicast listener", func(wc *mgr.WorkerCtx) error {
|
||||
return listenForDNSPackets(wc.Ctx(), multicast4Conn, messages)
|
||||
})
|
||||
defer func() {
|
||||
_ = multicast4Conn.Close()
|
||||
@@ -99,8 +100,8 @@ func listenToMDNS(ctx context.Context) error {
|
||||
// TODO: retry after some time
|
||||
log.Warningf("intel(mdns): failed to create udp4 listen socket: %s", err)
|
||||
} else {
|
||||
module.StartServiceWorker("mdns udp4 unicast listener", 0, func(ctx context.Context) error {
|
||||
return listenForDNSPackets(ctx, unicast4Conn, messages)
|
||||
module.mgr.Go("mdns udp4 unicast listener", func(wc *mgr.WorkerCtx) error {
|
||||
return listenForDNSPackets(wc.Ctx(), unicast4Conn, messages)
|
||||
})
|
||||
defer func() {
|
||||
_ = unicast4Conn.Close()
|
||||
@@ -113,8 +114,8 @@ func listenToMDNS(ctx context.Context) error {
|
||||
// TODO: retry after some time
|
||||
log.Warningf("intel(mdns): failed to create udp6 listen multicast socket: %s", err)
|
||||
} else {
|
||||
module.StartServiceWorker("mdns udp6 multicast listener", 0, func(ctx context.Context) error {
|
||||
return listenForDNSPackets(ctx, multicast6Conn, messages)
|
||||
module.mgr.Go("mdns udp6 multicast listener", func(wc *mgr.WorkerCtx) error {
|
||||
return listenForDNSPackets(wc.Ctx(), multicast6Conn, messages)
|
||||
})
|
||||
defer func() {
|
||||
_ = multicast6Conn.Close()
|
||||
@@ -126,8 +127,8 @@ func listenToMDNS(ctx context.Context) error {
|
||||
// TODO: retry after some time
|
||||
log.Warningf("intel(mdns): failed to create udp6 listen socket: %s", err)
|
||||
} else {
|
||||
module.StartServiceWorker("mdns udp6 unicast listener", 0, func(ctx context.Context) error {
|
||||
return listenForDNSPackets(ctx, unicast6Conn, messages)
|
||||
module.mgr.Go("mdns udp6 unicast listener", func(wc *mgr.WorkerCtx) error {
|
||||
return listenForDNSPackets(wc.Ctx(), unicast6Conn, messages)
|
||||
})
|
||||
defer func() {
|
||||
_ = unicast6Conn.Close()
|
||||
@@ -138,12 +139,12 @@ func listenToMDNS(ctx context.Context) error {
|
||||
}
|
||||
|
||||
// start message handler
|
||||
module.StartServiceWorker("mdns message handler", 0, func(ctx context.Context) error {
|
||||
return handleMDNSMessages(ctx, messages)
|
||||
module.mgr.Go("mdns message handler", func(wc *mgr.WorkerCtx) error {
|
||||
return handleMDNSMessages(wc.Ctx(), messages)
|
||||
})
|
||||
|
||||
// wait for shutdown
|
||||
<-module.Ctx.Done()
|
||||
<-wc.Done()
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -341,7 +342,7 @@ func listenForDNSPackets(ctx context.Context, conn *net.UDPConn, messages chan *
|
||||
for {
|
||||
n, err := conn.Read(buf)
|
||||
if err != nil {
|
||||
if module.IsStopping() {
|
||||
if module.mgr.IsDone() {
|
||||
return nil
|
||||
}
|
||||
log.Debugf("resolver: failed to read packet: %s", err)
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
|
||||
"github.com/miekg/dns"
|
||||
|
||||
"github.com/safing/portbase/log"
|
||||
"github.com/safing/portmaster/base/log"
|
||||
"github.com/safing/portmaster/service/netenv"
|
||||
)
|
||||
|
||||
|
||||
@@ -12,7 +12,8 @@ import (
|
||||
"github.com/miekg/dns"
|
||||
"github.com/tevino/abool"
|
||||
|
||||
"github.com/safing/portbase/log"
|
||||
"github.com/safing/portmaster/base/log"
|
||||
"github.com/safing/portmaster/service/mgr"
|
||||
"github.com/safing/portmaster/service/netenv"
|
||||
)
|
||||
|
||||
@@ -119,7 +120,7 @@ func (tr *TCPResolver) getOrCreateResolverConn(ctx context.Context) (*tcpResolve
|
||||
log.Warningf("resolver: heartbeat for dns client %s failed", tr.resolver.Info.DescriptiveName())
|
||||
case <-ctx.Done():
|
||||
return nil, ctx.Err()
|
||||
case <-module.Stopping():
|
||||
case <-module.mgr.Done():
|
||||
return nil, ErrShuttingDown
|
||||
}
|
||||
} else {
|
||||
@@ -127,7 +128,7 @@ func (tr *TCPResolver) getOrCreateResolverConn(ctx context.Context) (*tcpResolve
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return nil, ctx.Err()
|
||||
case <-module.Stopping():
|
||||
case <-module.mgr.Done():
|
||||
return nil, ErrShuttingDown
|
||||
default:
|
||||
}
|
||||
@@ -175,7 +176,7 @@ func (tr *TCPResolver) getOrCreateResolverConn(ctx context.Context) (*tcpResolve
|
||||
}
|
||||
|
||||
// Start worker.
|
||||
module.StartWorker("dns client", resolverConn.handler)
|
||||
module.mgr.Go("dns client", resolverConn.handler)
|
||||
|
||||
// Set resolver conn for reuse.
|
||||
tr.resolverConn = resolverConn
|
||||
@@ -204,7 +205,7 @@ func (tr *TCPResolver) Query(ctx context.Context, q *Query) (*RRCache, error) {
|
||||
case resolverConn.queries <- tq:
|
||||
case <-ctx.Done():
|
||||
return nil, ctx.Err()
|
||||
case <-module.Stopping():
|
||||
case <-module.mgr.Done():
|
||||
return nil, ErrShuttingDown
|
||||
case <-time.After(defaultRequestTimeout):
|
||||
return nil, ErrTimeout
|
||||
@@ -216,7 +217,7 @@ func (tr *TCPResolver) Query(ctx context.Context, q *Query) (*RRCache, error) {
|
||||
case reply = <-tq.Response:
|
||||
case <-ctx.Done():
|
||||
return nil, ctx.Err()
|
||||
case <-module.Stopping():
|
||||
case <-module.mgr.Done():
|
||||
return nil, ErrShuttingDown
|
||||
case <-time.After(defaultRequestTimeout):
|
||||
return nil, ErrTimeout
|
||||
@@ -282,9 +283,9 @@ func (trc *tcpResolverConn) shutdown() {
|
||||
}
|
||||
}
|
||||
|
||||
func (trc *tcpResolverConn) handler(workerCtx context.Context) error {
|
||||
func (trc *tcpResolverConn) handler(workerCtx *mgr.WorkerCtx) error {
|
||||
// Set up context and cleanup.
|
||||
trc.ctx, trc.cancelCtx = context.WithCancel(workerCtx)
|
||||
trc.ctx, trc.cancelCtx = context.WithCancel(workerCtx.Ctx())
|
||||
defer trc.shutdown()
|
||||
|
||||
// Set up variables.
|
||||
@@ -292,7 +293,7 @@ func (trc *tcpResolverConn) handler(workerCtx context.Context) error {
|
||||
ttlTimer := time.After(defaultClientTTL)
|
||||
|
||||
// Start connection reader.
|
||||
module.StartWorker("dns client reader", trc.reader)
|
||||
module.mgr.Go("dns client reader", trc.reader)
|
||||
|
||||
// Handle requests.
|
||||
for {
|
||||
@@ -357,7 +358,7 @@ func (trc *tcpResolverConn) handler(workerCtx context.Context) error {
|
||||
// assignUniqueID makes sure that ID assigned to msg is unique.
|
||||
func (trc *tcpResolverConn) assignUniqueID(msg *dns.Msg) {
|
||||
// try a random ID 10000 times
|
||||
for i := 0; i < 10000; i++ { // don't try forever
|
||||
for range 10000 { // don't try forever
|
||||
_, exists := trc.inFlightQueries[msg.Id]
|
||||
if !exists {
|
||||
return // we are unique, yay!
|
||||
@@ -416,7 +417,7 @@ func (trc *tcpResolverConn) handleQueryResponse(msg *dns.Msg) {
|
||||
}
|
||||
}
|
||||
|
||||
func (trc *tcpResolverConn) reader(workerCtx context.Context) error {
|
||||
func (trc *tcpResolverConn) reader(workerCtx *mgr.WorkerCtx) error {
|
||||
defer trc.cancelCtx()
|
||||
|
||||
for {
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
"github.com/miekg/dns"
|
||||
"github.com/tevino/abool"
|
||||
|
||||
"github.com/safing/portbase/utils"
|
||||
"github.com/safing/portmaster/base/utils"
|
||||
"github.com/safing/portmaster/service/netenv"
|
||||
"github.com/safing/portmaster/service/network/netutils"
|
||||
)
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
"github.com/miekg/dns"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/safing/portbase/log"
|
||||
"github.com/safing/portmaster/base/log"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -62,7 +62,7 @@ func TestSingleResolving(t *testing.T) {
|
||||
|
||||
wg := &sync.WaitGroup{}
|
||||
wg.Add(100)
|
||||
for i := 0; i < 100; i++ {
|
||||
for range 100 {
|
||||
startQuery(t, wg, resolver.Conn, &Query{
|
||||
FQDN: <-domainFeed,
|
||||
QType: dns.Type(dns.TypeA),
|
||||
@@ -94,7 +94,7 @@ func TestBulkResolving(t *testing.T) {
|
||||
|
||||
wg := &sync.WaitGroup{}
|
||||
wg.Add(100)
|
||||
for i := 0; i < 100; i++ {
|
||||
for range 100 {
|
||||
go startQuery(t, wg, resolver.Conn, &Query{
|
||||
FQDN: <-domainFeed,
|
||||
QType: dns.Type(dns.TypeA),
|
||||
|
||||
@@ -13,8 +13,9 @@ import (
|
||||
"github.com/miekg/dns"
|
||||
"golang.org/x/net/publicsuffix"
|
||||
|
||||
"github.com/safing/portbase/log"
|
||||
"github.com/safing/portbase/utils"
|
||||
"github.com/safing/portmaster/base/log"
|
||||
"github.com/safing/portmaster/base/utils"
|
||||
"github.com/safing/portmaster/service/mgr"
|
||||
"github.com/safing/portmaster/service/netenv"
|
||||
"github.com/safing/portmaster/service/network/netutils"
|
||||
)
|
||||
@@ -386,15 +387,15 @@ func loadResolvers() {
|
||||
defer resolversLock.Unlock()
|
||||
|
||||
// Resolve module error about missing resolvers.
|
||||
module.Resolve(missingResolversErrorID)
|
||||
module.states.Remove(missingResolversErrorID)
|
||||
|
||||
// Check if settings were changed and clear name cache when they did.
|
||||
newResolverConfig := configuredNameServers()
|
||||
if len(currentResolverConfig) > 0 &&
|
||||
!utils.StringSliceEqual(currentResolverConfig, newResolverConfig) {
|
||||
module.StartWorker("clear dns cache", func(ctx context.Context) error {
|
||||
module.mgr.Go("clear dns cache", func(ctx *mgr.WorkerCtx) error {
|
||||
log.Info("resolver: clearing dns cache due to changed resolver config")
|
||||
_, err := clearNameCache(ctx)
|
||||
_, err := clearNameCache(ctx.Ctx())
|
||||
return err
|
||||
})
|
||||
}
|
||||
@@ -410,18 +411,20 @@ func loadResolvers() {
|
||||
newResolvers = getConfiguredResolvers(defaultNameServers)
|
||||
if len(newResolvers) > 0 {
|
||||
log.Warning("resolver: no (valid) dns server found in config or system, falling back to global defaults")
|
||||
module.Warning(
|
||||
missingResolversErrorID,
|
||||
"Using Factory Default DNS Servers",
|
||||
"The Portmaster could not find any (valid) DNS servers in the settings or system. In order to prevent being disconnected, the factory defaults are being used instead. If you just switched your network, this should be resolved shortly.",
|
||||
)
|
||||
module.states.Add(mgr.State{
|
||||
ID: missingResolversErrorID,
|
||||
Name: "Using Factory Default DNS Servers",
|
||||
Message: "The Portmaster could not find any (valid) DNS servers in the settings or system. In order to prevent being disconnected, the factory defaults are being used instead. If you just switched your network, this should be resolved shortly.",
|
||||
Type: mgr.StateTypeWarning,
|
||||
})
|
||||
} else {
|
||||
log.Critical("resolver: no (valid) dns server found in config, system or global defaults")
|
||||
module.Error(
|
||||
missingResolversErrorID,
|
||||
"No DNS Servers Configured",
|
||||
"The Portmaster could not find any (valid) DNS servers in the settings or system. You will experience severe connectivity problems until resolved. If you just switched your network, this should be resolved shortly.",
|
||||
)
|
||||
module.states.Add(mgr.State{
|
||||
ID: missingResolversErrorID,
|
||||
Name: "No DNS Servers Configured",
|
||||
Message: "The Portmaster could not find any (valid) DNS servers in the settings or system. You will experience severe connectivity problems until resolved. If you just switched your network, this should be resolved shortly.",
|
||||
Type: mgr.StateTypeError,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
|
||||
"github.com/miekg/dns"
|
||||
|
||||
"github.com/safing/portbase/log"
|
||||
"github.com/safing/portmaster/base/log"
|
||||
)
|
||||
|
||||
// ResolveIPAndValidate finds (reverse DNS), validates (forward DNS) and returns the domain name assigned to the given IP.
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/safing/portbase/log"
|
||||
"github.com/safing/portmaster/base/log"
|
||||
)
|
||||
|
||||
func testReverse(t *testing.T, ip, result, expectedErr string) {
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
|
||||
"github.com/miekg/dns"
|
||||
|
||||
"github.com/safing/portbase/log"
|
||||
"github.com/safing/portmaster/base/log"
|
||||
"github.com/safing/portmaster/service/nameserver/nsutil"
|
||||
"github.com/safing/portmaster/service/netenv"
|
||||
)
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
|
||||
"github.com/miekg/dns"
|
||||
|
||||
"github.com/safing/portbase/log"
|
||||
"github.com/safing/portmaster/base/log"
|
||||
"github.com/safing/portmaster/service/netenv"
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user