mirror of
https://github.com/safing/portmaster
synced 2025-04-19 18:39:10 +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>
124 lines
2.8 KiB
Go
124 lines
2.8 KiB
Go
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()
|
|
}
|
|
}
|