mirror of
https://github.com/safing/portmaster
synced 2025-04-22 20:09:09 +00:00
* 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>
150 lines
4.3 KiB
Go
150 lines
4.3 KiB
Go
package docks
|
|
|
|
import (
|
|
"fmt"
|
|
"sync"
|
|
"time"
|
|
|
|
"github.com/tevino/abool"
|
|
|
|
"github.com/safing/portmaster/spn/hub"
|
|
"github.com/safing/portmaster/spn/terminal"
|
|
"github.com/safing/structures/container"
|
|
)
|
|
|
|
// ExpansionTerminal is used for expanding to another Hub.
|
|
type ExpansionTerminal struct {
|
|
*terminal.TerminalBase
|
|
|
|
relayOp *ExpansionTerminalRelayOp
|
|
|
|
changeNotifyFuncReady *abool.AtomicBool
|
|
changeNotifyFunc func()
|
|
|
|
reachableChecked time.Time
|
|
reachableLock sync.Mutex
|
|
}
|
|
|
|
// ExpansionTerminalRelayOp is the operation that connects to the relay.
|
|
type ExpansionTerminalRelayOp struct {
|
|
terminal.OperationBase
|
|
|
|
expansionTerminal *ExpansionTerminal
|
|
}
|
|
|
|
// Type returns the type ID.
|
|
func (op *ExpansionTerminalRelayOp) Type() string {
|
|
return ExpandOpType
|
|
}
|
|
|
|
// ExpandTo initiates an expansion.
|
|
func ExpandTo(from terminal.Terminal, routeTo string, encryptFor *hub.Hub) (*ExpansionTerminal, *terminal.Error) {
|
|
// First, create the local endpoint terminal to generate the init data.
|
|
|
|
// Create options and bare expansion terminal.
|
|
opts := terminal.DefaultExpansionTerminalOpts()
|
|
opts.Encrypt = encryptFor != nil
|
|
expansion := &ExpansionTerminal{
|
|
changeNotifyFuncReady: abool.New(),
|
|
}
|
|
expansion.relayOp = &ExpansionTerminalRelayOp{
|
|
expansionTerminal: expansion,
|
|
}
|
|
|
|
// Create base terminal for expansion.
|
|
base, initData, tErr := terminal.NewLocalBaseTerminal(
|
|
module.mgr.Ctx(),
|
|
0, // Ignore; The ID of the operation is used for communication.
|
|
from.FmtID(),
|
|
encryptFor,
|
|
opts,
|
|
expansion.relayOp,
|
|
)
|
|
if tErr != nil {
|
|
return nil, tErr.Wrap("failed to create expansion terminal base")
|
|
}
|
|
expansion.TerminalBase = base
|
|
base.SetTerminalExtension(expansion)
|
|
base.SetTimeout(defaultTerminalIdleTimeout)
|
|
|
|
// Second, start the actual relay operation.
|
|
|
|
// Create setup message for relay operation.
|
|
opInitData := container.New()
|
|
opInitData.AppendAsBlock([]byte(routeTo))
|
|
opInitData.AppendContainer(initData)
|
|
|
|
// Start relay operation on connected Hub.
|
|
tErr = from.StartOperation(expansion.relayOp, opInitData, 5*time.Second)
|
|
if tErr != nil {
|
|
return nil, tErr.Wrap("failed to start expansion operation")
|
|
}
|
|
|
|
// Start Workers.
|
|
base.StartWorkers(module.mgr, "expansion terminal")
|
|
|
|
return expansion, nil
|
|
}
|
|
|
|
// SetChangeNotifyFunc sets a callback function that is called when the terminal state changes.
|
|
func (t *ExpansionTerminal) SetChangeNotifyFunc(f func()) {
|
|
if t.changeNotifyFuncReady.IsSet() {
|
|
return
|
|
}
|
|
t.changeNotifyFunc = f
|
|
t.changeNotifyFuncReady.Set()
|
|
}
|
|
|
|
// NeedsReachableCheck returns whether the terminal should be checked if it is
|
|
// reachable via the existing network internal relayed connection.
|
|
func (t *ExpansionTerminal) NeedsReachableCheck(maxCheckAge time.Duration) bool {
|
|
t.reachableLock.Lock()
|
|
defer t.reachableLock.Unlock()
|
|
|
|
return time.Since(t.reachableChecked) > maxCheckAge
|
|
}
|
|
|
|
// MarkReachable marks the terminal as reachable via the existing network
|
|
// internal relayed connection.
|
|
func (t *ExpansionTerminal) MarkReachable() {
|
|
t.reachableLock.Lock()
|
|
defer t.reachableLock.Unlock()
|
|
|
|
t.reachableChecked = time.Now()
|
|
}
|
|
|
|
// HandleDestruction gives the terminal the ability to clean up.
|
|
// The terminal has already fully shut down at this point.
|
|
// Should never be called directly. Call Abandon() instead.
|
|
func (t *ExpansionTerminal) HandleDestruction(err *terminal.Error) {
|
|
// Trigger update of connected Pin.
|
|
if t.changeNotifyFuncReady.IsSet() {
|
|
t.changeNotifyFunc()
|
|
}
|
|
|
|
// Stop the relay operation.
|
|
// The error message is arlready sent by the terminal.
|
|
t.relayOp.Stop(t.relayOp, nil)
|
|
}
|
|
|
|
// CustomIDFormat formats the terminal ID.
|
|
func (t *ExpansionTerminal) CustomIDFormat() string {
|
|
return fmt.Sprintf("%s~%d", t.relayOp.Terminal().FmtID(), t.relayOp.ID())
|
|
}
|
|
|
|
// Deliver delivers a message to the operation.
|
|
func (op *ExpansionTerminalRelayOp) Deliver(msg *terminal.Msg) *terminal.Error {
|
|
// Proxy directly to expansion terminal.
|
|
return op.expansionTerminal.Deliver(msg)
|
|
}
|
|
|
|
// HandleStop gives the operation the ability to cleanly shut down.
|
|
// The returned error is the error to send to the other side.
|
|
// Should never be called directly. Call Stop() instead.
|
|
func (op *ExpansionTerminalRelayOp) HandleStop(err *terminal.Error) (errorToSend *terminal.Error) {
|
|
// Stop the expansion terminal.
|
|
// The error message will be sent by the operation.
|
|
op.expansionTerminal.Abandon(nil)
|
|
|
|
return err
|
|
}
|