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:
124
base/rng/entropy.go
Normal file
124
base/rng/entropy.go
Normal file
@@ -0,0 +1,124 @@
|
||||
package rng
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
|
||||
"github.com/tevino/abool"
|
||||
|
||||
"github.com/safing/portmaster/service/mgr"
|
||||
"github.com/safing/structures/container"
|
||||
)
|
||||
|
||||
const (
|
||||
minFeedEntropy = 256
|
||||
)
|
||||
|
||||
var rngFeeder = make(chan []byte)
|
||||
|
||||
// The Feeder is used to feed entropy to the RNG.
|
||||
type Feeder struct {
|
||||
input chan *entropyData
|
||||
entropy int64
|
||||
needsEntropy *abool.AtomicBool
|
||||
buffer *container.Container
|
||||
}
|
||||
|
||||
type entropyData struct {
|
||||
data []byte
|
||||
entropy int
|
||||
}
|
||||
|
||||
// NewFeeder returns a new entropy Feeder.
|
||||
func NewFeeder() *Feeder {
|
||||
newFeeder := &Feeder{
|
||||
input: make(chan *entropyData),
|
||||
needsEntropy: abool.NewBool(true),
|
||||
buffer: container.New(),
|
||||
}
|
||||
module.mgr.Go("feeder", newFeeder.run)
|
||||
return newFeeder
|
||||
}
|
||||
|
||||
// NeedsEntropy returns whether the feeder is currently gathering entropy.
|
||||
func (f *Feeder) NeedsEntropy() bool {
|
||||
return f.needsEntropy.IsSet()
|
||||
}
|
||||
|
||||
// SupplyEntropy supplies entropy to the Feeder, it will block until the Feeder has read from it.
|
||||
func (f *Feeder) SupplyEntropy(data []byte, entropy int) {
|
||||
f.input <- &entropyData{
|
||||
data: data,
|
||||
entropy: entropy,
|
||||
}
|
||||
}
|
||||
|
||||
// SupplyEntropyIfNeeded supplies entropy to the Feeder, but will not block if no entropy is currently needed.
|
||||
func (f *Feeder) SupplyEntropyIfNeeded(data []byte, entropy int) {
|
||||
if f.needsEntropy.IsSet() {
|
||||
return
|
||||
}
|
||||
|
||||
select {
|
||||
case f.input <- &entropyData{
|
||||
data: data,
|
||||
entropy: entropy,
|
||||
}:
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
// SupplyEntropyAsInt supplies entropy to the Feeder, it will block until the Feeder has read from it.
|
||||
func (f *Feeder) SupplyEntropyAsInt(n int64, entropy int) {
|
||||
b := make([]byte, 8)
|
||||
binary.LittleEndian.PutUint64(b, uint64(n))
|
||||
f.SupplyEntropy(b, entropy)
|
||||
}
|
||||
|
||||
// SupplyEntropyAsIntIfNeeded supplies entropy to the Feeder, but will not block if no entropy is currently needed.
|
||||
func (f *Feeder) SupplyEntropyAsIntIfNeeded(n int64, entropy int) {
|
||||
if f.needsEntropy.IsSet() { // avoid allocating a slice if possible
|
||||
b := make([]byte, 8)
|
||||
binary.LittleEndian.PutUint64(b, uint64(n))
|
||||
f.SupplyEntropyIfNeeded(b, entropy)
|
||||
}
|
||||
}
|
||||
|
||||
// CloseFeeder stops the feed processing - the responsible goroutine exits. The input channel is closed and the feeder may not be used anymore in any way.
|
||||
func (f *Feeder) CloseFeeder() {
|
||||
close(f.input)
|
||||
}
|
||||
|
||||
func (f *Feeder) run(ctx *mgr.WorkerCtx) error {
|
||||
defer f.needsEntropy.UnSet()
|
||||
|
||||
for {
|
||||
// gather
|
||||
f.needsEntropy.Set()
|
||||
gather:
|
||||
for {
|
||||
select {
|
||||
case newEntropy := <-f.input:
|
||||
// check if feed has been closed
|
||||
if newEntropy == nil {
|
||||
return nil
|
||||
}
|
||||
// append to buffer
|
||||
f.buffer.Append(newEntropy.data)
|
||||
f.entropy += int64(newEntropy.entropy)
|
||||
if f.entropy >= minFeedEntropy {
|
||||
break gather
|
||||
}
|
||||
case <-ctx.Done():
|
||||
return nil
|
||||
}
|
||||
}
|
||||
// feed
|
||||
f.needsEntropy.UnSet()
|
||||
select {
|
||||
case rngFeeder <- f.buffer.CompileData():
|
||||
case <-ctx.Done():
|
||||
return nil
|
||||
}
|
||||
f.buffer = container.New()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user