mirror of
https://github.com/evilsocket/opensnitch.git
synced 2025-03-04 08:34:40 +01:00
maintain a cache of struct Process for currently active PIDs (#342)
* maintain a cache of struct Process for currently active PIDs decreases PID lookup time from ~100usec to ~5usec * Update activepids.go remove import "os" Co-authored-by: themighty1 <you@example.com>
This commit is contained in:
parent
b0e50f2f11
commit
af9c17ceb8
3 changed files with 91 additions and 0 deletions
85
daemon/procmon/activepids.go
Normal file
85
daemon/procmon/activepids.go
Normal file
|
@ -0,0 +1,85 @@
|
|||
package procmon
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/evilsocket/opensnitch/daemon/log"
|
||||
"io/ioutil"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
type value struct {
|
||||
Process *Process
|
||||
//Starttime uniquely identifies a process, it is the 22nd value in /proc/<PID>/stat
|
||||
//if another process starts with the same PID, it's Starttime will be unique
|
||||
Starttime uint32
|
||||
}
|
||||
|
||||
var (
|
||||
activePids = make(map[uint32]value)
|
||||
activePidsLock = sync.RWMutex{}
|
||||
)
|
||||
|
||||
//monitorActivePids checks that each process in activePids
|
||||
//is still running and if not running (or another process with the same pid is running),
|
||||
//removes the pid from activePids
|
||||
func monitorActivePids() {
|
||||
for {
|
||||
time.Sleep(time.Second)
|
||||
activePidsLock.Lock()
|
||||
for k, v := range activePids {
|
||||
data, err := ioutil.ReadFile(fmt.Sprintf("/proc/%d/stat", k))
|
||||
if err != nil {
|
||||
//file does not exists, pid has quit
|
||||
delete(activePids, k)
|
||||
continue
|
||||
}
|
||||
startTime, err := strconv.Atoi(strings.Split(string(data), " ")[21])
|
||||
if err != nil {
|
||||
log.Error("Could not find or convert Starttime. This should never happen. Please report this incident to the Opensnitch developers.")
|
||||
delete(activePids, k)
|
||||
continue
|
||||
}
|
||||
if uint32(startTime) != v.Starttime {
|
||||
//extremely unlikely: the original process has quit and another process
|
||||
//was started with the same PID - all this in less than 1 second
|
||||
log.Error("Same PID but different Starttime. Please report this incident to the Opensnitch developers.")
|
||||
delete(activePids, k)
|
||||
continue
|
||||
}
|
||||
}
|
||||
activePidsLock.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
func findProcessInActivePidsCache(pid uint32) *Process {
|
||||
activePidsLock.Lock()
|
||||
defer activePidsLock.Unlock()
|
||||
if value, ok := activePids[pid]; ok {
|
||||
return value.Process
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func addToActivePidsCache(pid uint32, proc *Process) {
|
||||
|
||||
data, err := ioutil.ReadFile(fmt.Sprintf("/proc/%d/stat", pid))
|
||||
if err != nil {
|
||||
//most likely the process has quit by now
|
||||
return
|
||||
}
|
||||
startTime, err2 := strconv.Atoi(strings.Split(string(data), " ")[21])
|
||||
if err2 != nil {
|
||||
log.Error("Could not find or convert Starttime. This should never happen. Please report this incident to the Opensnitch developers.")
|
||||
return
|
||||
}
|
||||
|
||||
activePidsLock.Lock()
|
||||
activePids[pid] = value{
|
||||
Process: proc,
|
||||
Starttime: uint32(startTime),
|
||||
}
|
||||
activePidsLock.Unlock()
|
||||
}
|
|
@ -107,6 +107,10 @@ func FindProcess(pid int, interceptUnknown bool) *Process {
|
|||
}
|
||||
}
|
||||
|
||||
if proc := findProcessInActivePidsCache(uint32(pid)); proc != nil {
|
||||
return proc
|
||||
}
|
||||
|
||||
linkName := fmt.Sprint("/proc/", pid, "/exe")
|
||||
if _, err := os.Lstat(linkName); err != nil {
|
||||
return nil
|
||||
|
@ -120,6 +124,7 @@ func FindProcess(pid int, interceptUnknown bool) *Process {
|
|||
proc.readEnv()
|
||||
proc.cleanPath()
|
||||
|
||||
addToActivePidsCache(uint32(pid), proc)
|
||||
return proc
|
||||
}
|
||||
return nil
|
||||
|
|
|
@ -125,4 +125,5 @@ func Init() {
|
|||
// if any of the above methods have failed, fallback to proc
|
||||
log.Info("Process monitor method /proc")
|
||||
SetMonitorMethod(MethodProc)
|
||||
go monitorActivePids()
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue