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:
@@ -1,27 +1,46 @@
|
||||
package customlists
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"golang.org/x/net/publicsuffix"
|
||||
|
||||
"github.com/safing/portbase/api"
|
||||
"github.com/safing/portbase/modules"
|
||||
"github.com/safing/portmaster/base/api"
|
||||
"github.com/safing/portmaster/base/config"
|
||||
"github.com/safing/portmaster/service/mgr"
|
||||
)
|
||||
|
||||
var module *modules.Module
|
||||
type CustomList struct {
|
||||
mgr *mgr.Manager
|
||||
instance instance
|
||||
|
||||
const (
|
||||
configModuleName = "config"
|
||||
configChangeEvent = "config change"
|
||||
)
|
||||
updateFilterListWorkerMgr *mgr.WorkerMgr
|
||||
|
||||
states *mgr.StateMgr
|
||||
}
|
||||
|
||||
func (cl *CustomList) Manager() *mgr.Manager {
|
||||
return cl.mgr
|
||||
}
|
||||
|
||||
func (cl *CustomList) States() *mgr.StateMgr {
|
||||
return cl.states
|
||||
}
|
||||
|
||||
func (cl *CustomList) Start() error {
|
||||
return start()
|
||||
}
|
||||
|
||||
func (cl *CustomList) Stop() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Helper variables for parsing the input file.
|
||||
var (
|
||||
@@ -34,17 +53,12 @@ var (
|
||||
filterListFileModifiedTime time.Time
|
||||
|
||||
filterListLock sync.RWMutex
|
||||
parserTask *modules.Task
|
||||
|
||||
// ErrNotConfigured is returned when updating the custom filter list, but it
|
||||
// is not configured.
|
||||
ErrNotConfigured = errors.New("custom filter list not configured")
|
||||
)
|
||||
|
||||
func init() {
|
||||
module = modules.Register("customlists", prep, start, nil, "base")
|
||||
}
|
||||
|
||||
func prep() error {
|
||||
initFilterLists()
|
||||
|
||||
@@ -56,11 +70,10 @@ func prep() error {
|
||||
|
||||
// Register api endpoint for updating the filter list.
|
||||
if err := api.RegisterEndpoint(api.Endpoint{
|
||||
Path: "customlists/update",
|
||||
Write: api.PermitUser,
|
||||
BelongsTo: module,
|
||||
Path: "customlists/update",
|
||||
Write: api.PermitUser,
|
||||
ActionFunc: func(ar *api.Request) (msg string, err error) {
|
||||
errCheck := checkAndUpdateFilterList()
|
||||
errCheck := checkAndUpdateFilterList(nil)
|
||||
if errCheck != nil {
|
||||
return "", errCheck
|
||||
}
|
||||
@@ -77,30 +90,23 @@ func prep() error {
|
||||
|
||||
func start() error {
|
||||
// Register to hook to update after config change.
|
||||
if err := module.RegisterEventHook(
|
||||
configModuleName,
|
||||
configChangeEvent,
|
||||
module.instance.Config().EventConfigChange.AddCallback(
|
||||
"update custom filter list",
|
||||
func(ctx context.Context, obj interface{}) error {
|
||||
if err := checkAndUpdateFilterList(); !errors.Is(err, ErrNotConfigured) {
|
||||
return err
|
||||
func(wc *mgr.WorkerCtx, _ struct{}) (bool, error) {
|
||||
if err := checkAndUpdateFilterList(wc); !errors.Is(err, ErrNotConfigured) {
|
||||
return false, err
|
||||
}
|
||||
return nil
|
||||
return false, nil
|
||||
},
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
)
|
||||
|
||||
// Create parser task and enqueue for execution. "checkAndUpdateFilterList" will schedule the next execution.
|
||||
parserTask = module.NewTask("intel/customlists:file-update-check", func(context.Context, *modules.Task) error {
|
||||
_ = checkAndUpdateFilterList()
|
||||
return nil
|
||||
}).Schedule(time.Now().Add(20 * time.Second))
|
||||
module.updateFilterListWorkerMgr.Delay(20 * time.Second).Repeat(1 * time.Minute)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkAndUpdateFilterList() error {
|
||||
func checkAndUpdateFilterList(_ *mgr.WorkerCtx) error {
|
||||
filterListLock.Lock()
|
||||
defer filterListLock.Unlock()
|
||||
|
||||
@@ -110,9 +116,6 @@ func checkAndUpdateFilterList() error {
|
||||
return ErrNotConfigured
|
||||
}
|
||||
|
||||
// Schedule next update check
|
||||
parserTask.Schedule(time.Now().Add(1 * time.Minute))
|
||||
|
||||
// Try to get file info
|
||||
modifiedTime := time.Now()
|
||||
if fileInfo, err := os.Stat(filePath); err == nil {
|
||||
@@ -205,3 +208,33 @@ func splitDomain(domain string) []string {
|
||||
}
|
||||
return domains
|
||||
}
|
||||
|
||||
var (
|
||||
module *CustomList
|
||||
shimLoaded atomic.Bool
|
||||
)
|
||||
|
||||
// New returns a new CustomList module.
|
||||
func New(instance instance) (*CustomList, error) {
|
||||
if !shimLoaded.CompareAndSwap(false, true) {
|
||||
return nil, errors.New("only one instance allowed")
|
||||
}
|
||||
m := mgr.New("CustomList")
|
||||
module = &CustomList{
|
||||
mgr: m,
|
||||
instance: instance,
|
||||
|
||||
states: mgr.NewStateMgr(m),
|
||||
updateFilterListWorkerMgr: m.NewWorkerMgr("update custom filter list", checkAndUpdateFilterList, nil),
|
||||
}
|
||||
|
||||
if err := prep(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return module, nil
|
||||
}
|
||||
|
||||
type instance interface {
|
||||
Config() *config.Config
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user