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:
Daniel Hååvi
2024-08-09 17:15:48 +02:00
committed by GitHub
parent 10a77498f4
commit 80664d1a27
647 changed files with 37690 additions and 3366 deletions

View File

@@ -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
}