feat(WIP): add pause and resume functionality for Portmaster/SPN
https://github.com/safing/portmaster/issues/2050
This commit is contained in:
@@ -34,6 +34,11 @@ func startInterception(packets chan packet.Packet) error {
|
||||
|
||||
// stop starts the interception.
|
||||
func stopInterception() error {
|
||||
// TODO: stop ebpf workers gracefully
|
||||
// E.g.:
|
||||
// module.mgr.Cancel()
|
||||
// <-m.Done()
|
||||
|
||||
return StopNfqueueInterception()
|
||||
}
|
||||
|
||||
|
||||
@@ -12,9 +12,7 @@ import (
|
||||
|
||||
var (
|
||||
packetMetricsDestination string
|
||||
metrics = &packetMetrics{
|
||||
done: make(chan struct{}),
|
||||
}
|
||||
metrics = &packetMetrics{}
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -40,6 +38,10 @@ func (pm *packetMetrics) record(tp *tracedPacket, verdict string) {
|
||||
pm.l.Lock()
|
||||
defer pm.l.Unlock()
|
||||
|
||||
if pm.done == nil {
|
||||
return
|
||||
}
|
||||
|
||||
pm.records = append(pm.records, &performanceRecord{
|
||||
start: start,
|
||||
duration: duration,
|
||||
@@ -48,6 +50,18 @@ func (pm *packetMetrics) record(tp *tracedPacket, verdict string) {
|
||||
}(tp.start.UnixNano(), time.Since(tp.start))
|
||||
}
|
||||
|
||||
func (pm *packetMetrics) stop() {
|
||||
pm.l.Lock()
|
||||
defer pm.l.Unlock()
|
||||
|
||||
if pm.done == nil {
|
||||
return
|
||||
}
|
||||
|
||||
close(pm.done)
|
||||
pm.done = nil
|
||||
}
|
||||
|
||||
func (pm *packetMetrics) writeMetrics() {
|
||||
if packetMetricsDestination == "" {
|
||||
return
|
||||
@@ -62,9 +76,14 @@ func (pm *packetMetrics) writeMetrics() {
|
||||
_ = f.Close()
|
||||
}()
|
||||
|
||||
pm.l.Lock()
|
||||
pm.done = make(chan struct{})
|
||||
done := pm.done
|
||||
pm.l.Unlock()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-pm.done:
|
||||
case <-done:
|
||||
return
|
||||
case <-time.After(time.Second * 5):
|
||||
}
|
||||
|
||||
@@ -40,6 +40,7 @@ var (
|
||||
BandwidthUpdates = make(chan *packet.BandwidthUpdate, 1000)
|
||||
|
||||
disableInterception bool
|
||||
isStarted atomic.Bool
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -53,6 +54,10 @@ func start() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
if !isStarted.CompareAndSwap(false, true) {
|
||||
return nil // already running
|
||||
}
|
||||
|
||||
inputPackets := Packets
|
||||
if packetMetricsDestination != "" {
|
||||
go metrics.writeMetrics()
|
||||
@@ -64,7 +69,16 @@ func start() error {
|
||||
}()
|
||||
}
|
||||
|
||||
return startInterception(inputPackets)
|
||||
err := startInterception(inputPackets)
|
||||
if err != nil {
|
||||
log.Errorf("interception: failed to start module: %q", err)
|
||||
log.Debug("interception: cleaning up after failed start...")
|
||||
if e := stopInterception(); e != nil {
|
||||
log.Debugf("interception: error cleaning up after failed start: %q", e.Error())
|
||||
}
|
||||
isStarted.Store(false)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Stop starts the interception.
|
||||
@@ -73,7 +87,11 @@ func stop() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
close(metrics.done)
|
||||
if !isStarted.CompareAndSwap(true, false) {
|
||||
return nil // not running
|
||||
}
|
||||
|
||||
metrics.stop()
|
||||
if err := stopInterception(); err != nil {
|
||||
log.Errorf("failed to stop interception module: %s", err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user